Skip to content

Commit

Permalink
Merge pull request #15 from defientco/sweets/cleanup
Browse files Browse the repository at this point in the history
Sweets/cleanup
  • Loading branch information
SweetmanTech authored Aug 6, 2023
2 parents fba41f6 + 3e94787 commit c06316f
Show file tree
Hide file tree
Showing 12 changed files with 331 additions and 301 deletions.
150 changes: 78 additions & 72 deletions src/ERC721ACH.sol
Original file line number Diff line number Diff line change
@@ -1,36 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import {IERC721ACH} from "./interfaces/IERC721ACH.sol";
import {ERC721AC} from "ERC721C/erc721c/ERC721AC.sol";
import {IERC721A} from "erc721a/contracts/IERC721A.sol";
import {IBeforeTokenTransfersHook} from "./interfaces/IBeforeTokenTransfersHook.sol";
import {IAfterTokenTransfersHook} from "./interfaces/IAfterTokenTransfersHook.sol";
import {IOwnerOfHook} from "./interfaces/IOwnerOfHook.sol";
import {IERC721ACH} from "./interfaces/IERC721ACH.sol";

/**
* @title ERC721ACH
* @author Cre8ors Inc.
* @notice Extends Limit Break's ERC721-AC implementation with Hook functionality, which
* allows the contract owner to override hooks associated with core ERC721 functions.
* @notice This contract extends Limit Break's ERC721-AC implementation with hook functionality.
* It allows the contract owner to set hooks that modify the behavior of core ERC721
* functions. Each hook type can be associated with a contract that implements the
* corresponding hook's logic. Only the contract owner can set or change these hooks.
*/
contract ERC721ACH is ERC721AC, IERC721ACH {


contract ERC721ACH is IERC721ACH, ERC721AC {
/**
* @dev Mapping of hook types to their respective contract addresses.
* Each hook type can be associated with a contract that implements the hook's logic.
* Only the contract owner can set or update these hooks.
*/
* @dev This mapping associates hook types with their corresponding contract addresses.
* Each hook type can be associated with a contract that implements the hook's logic.
* Only the contract owner can set or change these hooks.
*/
mapping(HookType => address) public hooks;


event UpdatedHook(address indexed setter, HookType hookType, address indexed hookAddress);


/// @notice Contract constructor
/// @param _contractName The name for the token contract
/// @param _contractSymbol The symbol for the token contract
/**
* @dev Contract constructor.
* @param _contractName The name of the token contract.
* @param _contractSymbol The symbol of the token contract.
*/
constructor(
string memory _contractName,
string memory _contractSymbol
Expand All @@ -47,81 +45,80 @@ contract ERC721ACH is ERC721AC, IERC721ACH {
/// ERC721 overrides
/////////////////////////////////////////////////



/// TODO
/**
* @notice Before token transfer hook. This function is called before any token transfer.
* This includes minting and burning.
* @param from The source address.
* @param to The destination address.
* @param startTokenId The ID of the first token to be transferred.
* @param quantity The number of tokens to be transferred.
*/
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual override {
super._beforeTokenTransfers(from, to, startTokenId, quantity);
IBeforeTokenTransfersHook beforeTokenTransfersHook = IBeforeTokenTransfersHook(hooks[HookType.BeforeTokenTransfers]);
if (
address(beforeTokenTransfersHook) != address(0) &&
beforeTokenTransfersHook.useBeforeTokenTransfersHook(from, to, startTokenId, quantity)
) {
beforeTokenTransfersHook.beforeTokenTransfersOverrideHook(
from,
to,
startTokenId,
quantity
);
}
IBeforeTokenTransfersHook hook = IBeforeTokenTransfersHook(
hooks[HookType.BeforeTokenTransfers]
);
if (address(hook) != address(0)) {
hook.beforeTokenTransfersHook(from, to, startTokenId, quantity);
}
}

/// TODO
/**
* @notice After token transfer hook. This function is called after any token transfer.
* This includes minting and burning.
* @param from The source address.
* @param to The destination address.
* @param startTokenId The ID of the first token to be transferred.
* @param quantity The number of tokens to be transferred.
*/
function _afterTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual override {

super._afterTokenTransfers(from, to, startTokenId, quantity);
IAfterTokenTransfersHook afterTokenTransfersHook = IAfterTokenTransfersHook(hooks[HookType.AfterTokenTransfers]);
if (
address(afterTokenTransfersHook) != address(0) &&
afterTokenTransfersHook.useAfterTokenTransfersHook(from, to, startTokenId, quantity)
) {
afterTokenTransfersHook.afterTokenTransfersOverrideHook(
from,
to,
startTokenId,
quantity
);
}
IAfterTokenTransfersHook hook = IAfterTokenTransfersHook(
hooks[HookType.AfterTokenTransfers]
);
if (address(hook) != address(0)) {
hook.afterTokenTransfersHook(from, to, startTokenId, quantity);
}
}

function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner;
/**
* @notice Returns the owner of the `tokenId` token.
* @dev The owner of a token is also its approver by default.
* @param tokenId The ID of the token to query.
* @return owner of the `tokenId` token.
*/
function ownerOf(
uint256 tokenId
) public view virtual override returns (address owner) {
bool runSuper;
IOwnerOfHook hook = IOwnerOfHook(hooks[HookType.OwnerOf]);

IOwnerOfHook ownerOfHook = IOwnerOfHook(hooks[HookType.OwnerOf]);

if (
address(ownerOfHook) != address(0) &&
ownerOfHook.useOwnerOfHook(tokenId)
) {
(owner, runSuper) = ownerOfHook.ownerOfOverrideHook(tokenId);
if (address(hook) != address(0)) {
(owner, runSuper) = hook.ownerOfHook(tokenId);
} else {
runSuper = true;
}

if (runSuper) {
owner = super.ownerOf(tokenId);
}

return owner;
}


/**
* @notice Returns the contract address for a specified hook type.
* @param hookType The type of hook to retrieve, as defined in the HookType enum.
* @return The address of the contract implementing the hook interface.
*/
* @notice Returns the address of the contract that implements the logic for the given hook type.
* @param hookType The type of the hook to query.
* @return address of the contract that implements the hook's logic.
*/
function getHook(HookType hookType) external view returns (address) {
return hooks[hookType];
}
Expand All @@ -130,26 +127,35 @@ contract ERC721ACH is ERC721AC, IERC721ACH {
/// ERC721C Override
/////////////////////////////////////////////////

/// @notice Override the function to throw if caller is not contract owner
/**
* @notice This internal function is used to ensure that the caller is the contract owner.
* @dev Throws if called by any account other than the owner.
*/
function _requireCallerIsContractOwner() internal view virtual override {}

/////////////////////////////////////////////////
/// ERC721H Admin Controls
/////////////////////////////////////////////////

/**
* @notice Sets the contract address for a specified hook type.
* @param hookType The type of hook to set, as defined in the HookType enum.
* @param hookAddress The address of the contract implementing the hook interface.
*/
function setHook(HookType hookType, address hookAddress) external virtual onlyOwner {
* @notice Updates the contract address for a specific hook type.
* @dev Throws if called by any account other than the owner.
* Emits a {UpdatedHook} event.
* @param hookType The type of the hook to set.
* @param hookAddress The address of the contract that implements the hook's logic.
*/
function setHook(
HookType hookType,
address hookAddress
) external virtual onlyOwner {
hooks[hookType] = hookAddress;
emit UpdatedHook(msg.sender, hookType, hookAddress);
}



/// TODO
/**
* @notice This modifier checks if the caller is the contract owner.
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_requireCallerIsContractOwner();

Expand Down
41 changes: 11 additions & 30 deletions src/interfaces/IAfterTokenTransfersHook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ pragma solidity ^0.8.15;
/// @title IAfterTokenTransfersHook
/// @dev Interface that defines hooks to be executed After token transfers.
interface IAfterTokenTransfersHook {

/**
@notice Emitted when the after token transfers hook is used.
@param from Address from which the tokens are being transferred.
@param to Address to which the tokens are being transferred.
@param startTokenId The starting ID of the tokens being transferred.
@param quantity The number of tokens being transferred.
* @notice Emitted when the after token transfers hook is used.
* @param from Address from which the tokens are being transferred.
* @param to Address to which the tokens are being transferred.
* @param startTokenId The starting ID of the tokens being transferred.
* @param quantity The number of tokens being transferred.
*/
event AfterTokenTransfersHookUsed(
address from,
Expand All @@ -21,30 +19,13 @@ interface IAfterTokenTransfersHook {
);

/**
@notice Checks if the token transfers function should use the custom hook.
@param from Address from which the tokens are being transferred.
@param to Address to which the tokens are being transferred.
@param startTokenId The starting ID of the tokens being transferred.
@param quantity The number of tokens being transferred.
@return A boolean indicating whether or not to use the custom hook for the token transfers function.
*/
function useAfterTokenTransfersHook(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) external view returns (bool);

/**
@notice Provides a custom implementation for the token transfers process.
@param from Address from which the tokens are being transferred.
@param to Address to which the tokens are being transferred.
@param startTokenId The starting ID of the tokens being transferred.
@param quantity The number of tokens being transferred.
* @notice Provides a custom implementation for the token transfers process.
* @param from Address from which the tokens are being transferred.
* @param to Address to which the tokens are being transferred.
* @param startTokenId The starting ID of the tokens being transferred.
* @param quantity The number of tokens being transferred.
*/
function afterTokenTransfersOverrideHook(
function afterTokenTransfersHook(
address from,
address to,
uint256 startTokenId,
Expand Down
41 changes: 11 additions & 30 deletions src/interfaces/IBeforeTokenTransfersHook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ pragma solidity ^0.8.15;
/// @title IBeforeTokenTransfersHook
/// @dev Interface that defines hooks to be executed before token transfers.
interface IBeforeTokenTransfersHook {

/**
@notice Emitted when the before token transfers hook is used.
@param from Address from which the tokens are being transferred.
@param to Address to which the tokens are being transferred.
@param startTokenId The starting ID of the tokens being transferred.
@param quantity The number of tokens being transferred.
* @notice Emitted when the before token transfers hook is used.
* @param from Address from which the tokens are being transferred.
* @param to Address to which the tokens are being transferred.
* @param startTokenId The starting ID of the tokens being transferred.
* @param quantity The number of tokens being transferred.
*/
event BeforeTokenTransfersHookUsed(
address from,
Expand All @@ -21,30 +19,13 @@ interface IBeforeTokenTransfersHook {
);

/**
@notice Checks if the token transfers function should use the custom hook.
@param from Address from which the tokens are being transferred.
@param to Address to which the tokens are being transferred.
@param startTokenId The starting ID of the tokens being transferred.
@param quantity The number of tokens being transferred.
@return A boolean indicating whether or not to use the custom hook for the token transfers function.
*/
function useBeforeTokenTransfersHook(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) external view returns (bool);

/**
@notice Provides a custom implementation for the token transfers process.
@param from Address from which the tokens are being transferred.
@param to Address to which the tokens are being transferred.
@param startTokenId The starting ID of the tokens being transferred.
@param quantity The number of tokens being transferred.
* @notice Provides a custom implementation for the token transfers process.
* @param from Address from which the tokens are being transferred.
* @param to Address to which the tokens are being transferred.
* @param startTokenId The starting ID of the tokens being transferred.
* @param quantity The number of tokens being transferred.
*/
function beforeTokenTransfersOverrideHook(
function beforeTokenTransfersHook(
address from,
address to,
uint256 startTokenId,
Expand Down
24 changes: 15 additions & 9 deletions src/interfaces/IERC721ACH.sol
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;


interface IERC721ACH {


/**
* @dev Enumerated list of all available hook types for the ERC721ACH contract.
*/
enum HookType {

* @dev Enumerated list of all available hook types for the ERC721ACH contract.
*/
enum HookType {
/// @notice Hook for custom logic before a token transfer occurs.
BeforeTokenTransfers,
/// @notice Hook for custom logic after a token transfer occurs.
AfterTokenTransfers,
/// @notice Hook for custom logic for ownerOf() function.
OwnerOf
OwnerOf
}

/**
* @notice An event that gets emitted when a hook is updated.
* @param setter The address that set the hook.
* @param hookType The type of the hook that was set.
* @param hookAddress The address of the contract that implements the hook.
*/
event UpdatedHook(
address indexed setter,
HookType hookType,
address indexed hookAddress
);

/**
* @notice Sets the contract address for a specified hook type.
Expand All @@ -32,5 +39,4 @@ interface IERC721ACH {
* @return The address of the contract implementing the hook interface.
*/
function getHook(HookType hookType) external view returns (address);

}
Loading

0 comments on commit c06316f

Please sign in to comment.