Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 5 from a total of 5 transactions
Loading...
Loading
Contract Name:
AxisMetadataRegistry
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: TBD pragma solidity 0.8.19; import {Ownable} from "@openzeppelin/access/Ownable.sol"; import {SignatureChecker} from "@openzeppelin/utils/cryptography/SignatureChecker.sol"; import {IAuctionHouse} from "@axis-core/interfaces/IAuctionHouse.sol"; contract AxisMetadataRegistry is Ownable { // ========== ERRORS ========== // error AlreadyAssigned(); error InvalidParam(string param); error InvalidSignature(); error NotAuthorized(); // ========== EVENTS ========== // event AuctionRegistered(address auctionHouse, uint96 lotId, string ipfsCID); event CuratorRegistered(address curator, uint256 xId, string ipfsCID); event CuratorUpdated(uint256 xId, string ipfsCID); // ========== DATA STRUCTURES ========== // struct CuratorRegistration { address curator; uint256 xId; string ipfsCID; } struct AuctionRegistration { address auctionHouse; uint96 lotId; string ipfsCID; } // ========== STATE VARIABLES ========== // // Typed Data Variables uint256 public chainId; bytes32 internal domainSeparator; bytes32 internal constant CURATOR_REGISTRATION_TYPEHASH = keccak256("CuratorRegistration(address curator,uint256 xId,string ipfsCID)"); /// @notice Address that signs registration payloads after being verified by an offchain service address public serviceSigner; mapping(address => bool) public isAuctionHouse; mapping(address curator => uint256 xId) public curatorId; mapping(uint256 xId => string ipfsCID) public curatorMetadata; mapping(address auctionHouse => mapping(uint96 lotId => string ipfsCID)) public auctionMetadata; // ========== CONSTRUCTOR ========== // constructor(address serviceSigner_, address[] memory auctionHouses_) { for (uint256 i = 0; i < auctionHouses_.length; i++) { isAuctionHouse[auctionHouses_[i]] = true; } serviceSigner = serviceSigner_; } // ========== INIT ========== // function registerCurator(CuratorRegistration calldata payload_, bytes calldata signature_) external { // Validate the sender is the curator listed in the payload if (msg.sender != payload_.curator) revert NotAuthorized(); // Validate the xId is not zero if (payload_.xId == 0) revert InvalidParam("payload.xId"); // Validate that the curator address is not already assigned an xId if (curatorId[payload_.curator] != 0) revert AlreadyAssigned(); // Validate that the ipfsCID string is not empty if (bytes(payload_.ipfsCID).length == 0) revert InvalidParam("payload.ipfsCID"); // Validate the service signer signed the payload if (!isValidSignature(serviceSigner, payload_, signature_)) revert InvalidSignature(); // Store the curator's xId curatorId[payload_.curator] = payload_.xId; // Store the metadata curatorMetadata[payload_.xId] = payload_.ipfsCID; // Emit event emit CuratorRegistered(payload_.curator, payload_.xId, payload_.ipfsCID); } // This function allows an auction to be registered multiple times, which allows updating the data function registerAuction(address auctionHouse_, uint96 lotId_, string calldata ipfsCID_) external { // Validate the auction house is supported if (!isAuctionHouse[auctionHouse_]) revert InvalidParam("auctionHouse"); IAuctionHouse auctionHouse = IAuctionHouse(auctionHouse_); // Validate the lotId is valid on the auction house by comparing against the lotCounter if (lotId_ >= auctionHouse.lotCounter()) revert InvalidParam("lotId"); // Validate the caller is the seller of the lot (address seller,,,,,,,,) = auctionHouse.lotRouting(lotId_); if (msg.sender != seller) revert NotAuthorized(); // Validate the ipfsCID string is not empty if (bytes(ipfsCID_).length == 0) revert InvalidParam("ipfsCID"); // Store the metadata auctionMetadata[auctionHouse_][lotId_] = ipfsCID_; // Emit event emit AuctionRegistered(auctionHouse_, lotId_, ipfsCID_); } // ========== UPDATE ========== // function updateCurator(uint256 xId_, string calldata ipfsCID_) external { // Validate the xId is not zero if (xId_ == 0) revert InvalidParam("xId"); // Validate the caller is the curator if (curatorId[msg.sender] != xId_) revert NotAuthorized(); // Validate the ipfsCID string is not empty if (bytes(ipfsCID_).length == 0) revert InvalidParam("ipfsCID"); // Store the metadata curatorMetadata[xId_] = ipfsCID_; // Emit event emit CuratorUpdated(xId_, ipfsCID_); } function addCuratorAddress(uint256 xId_, address curator_) external { // Validate the xId is not zero if (xId_ == 0) revert InvalidParam("xId"); // Validate the caller is a currently a valid address for the curator if (curatorId[msg.sender] != xId_) revert NotAuthorized(); // Validate the curator address is not already assigned an xId if (curatorId[curator_] != 0) revert AlreadyAssigned(); // Store the curator's xId curatorId[curator_] = xId_; } function removeCuratorAddress(uint256 xId_, address curator_) external { // Validate the xId is not zero if (xId_ == 0) revert InvalidParam("xId"); // Validate the caller is a currently a valid address for the curator if (curatorId[msg.sender] != xId_) revert NotAuthorized(); // Validate the curator address is assigned to the xId if (curatorId[curator_] != xId_) revert InvalidParam("curator"); // Remove the curator's xId delete curatorId[curator_]; } // ========== ADMIN ========== // function updateServiceSigner(address serviceSigner_) external onlyOwner { serviceSigner = serviceSigner_; } function addAuctionHouse(address auctionHouse_) external onlyOwner { isAuctionHouse[auctionHouse_] = true; } function removeAuctionHouse(address auctionHouse_) external onlyOwner { delete isAuctionHouse[auctionHouse_]; } // ========== SIGNATURE VALIDATION ========== // function isValidSignature(address signer_, CuratorRegistration calldata payload_, bytes calldata signature_) public view returns (bool) { return SignatureChecker.isValidSignatureNow(signer_, getDigest(payload_), signature_); } function getDigest(CuratorRegistration calldata payload_) public view returns (bytes32) { return keccak256( abi.encodePacked( hex"1901", DOMAIN_SEPARATOR(), keccak256( abi.encode( CURATOR_REGISTRATION_TYPEHASH, payload_.curator, payload_.xId, keccak256(bytes(payload_.ipfsCID)) ) ) ) ); } /* ========== DOMAIN SEPARATOR ========== */ function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == chainId ? domainSeparator : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256("Axis Metadata Registry"), keccak256("v1.0.0"), block.chainid, address(this) ) ); } function updateDomainSeparator() external { require(block.chainid != chainId, "DOMAIN_SEPARATOR_ALREADY_UPDATED"); chainId = block.chainid; domainSeparator = computeDomainSeparator(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol) pragma solidity ^0.8.0; import "./ECDSA.sol"; import "../../interfaces/IERC1271.sol"; /** * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like * Argent and Gnosis Safe. * * _Available since v4.1._ */ library SignatureChecker { /** * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`. * * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus * change through time. It could return true at block N and false at block N+1 (or the opposite). */ function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) { (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature); return (error == ECDSA.RecoverError.NoError && recovered == signer) || isValidERC1271SignatureNow(signer, hash, signature); } /** * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated * against the signer smart contract using ERC1271. * * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus * change through time. It could return true at block N and false at block N+1 (or the opposite). */ function isValidERC1271SignatureNow( address signer, bytes32 hash, bytes memory signature ) internal view returns (bool) { (bool success, bytes memory result) = signer.staticcall( abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature) ); return (success && result.length >= 32 && abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector)); } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity >=0.8.0; // Interfaces import {IAuction} from "./modules/IAuction.sol"; import {ICallback} from "./ICallback.sol"; import {IDerivative} from "./modules/IDerivative.sol"; // Internal dependencies import {Keycode, Veecode} from "../modules/Keycode.sol"; /// @title IAuctionHouse /// @notice Interface for the Axis AuctionHouse contracts interface IAuctionHouse { // ========= ERRORS ========= // error InvalidParams(); error InvalidLotId(uint96 id_); error InvalidState(); error InvalidCallback(); /// @notice Used when the caller is not permitted to perform that action error NotPermitted(address caller_); // ========= EVENTS ========= // /// @notice Emitted when a new auction lot is created /// /// @param lotId ID of the auction lot /// @param auctionRef Auction module, represented by its Veecode /// @param infoHash IPFS hash of the auction information event AuctionCreated(uint96 indexed lotId, Veecode indexed auctionRef, string infoHash); /// @notice Emitted when an auction lot is cancelled /// /// @param lotId ID of the auction lot /// @param auctionRef Auction module, represented by its Veecode event AuctionCancelled(uint96 indexed lotId, Veecode indexed auctionRef); /// @notice Emitted when a curator accepts curation of an auction lot /// /// @param lotId ID of the auction lot /// @param curator Address of the curator event Curated(uint96 indexed lotId, address indexed curator); // ========= DATA STRUCTURES ========== // /// @notice Auction routing information provided as input parameters /// /// @param auctionType Auction type, represented by the Keycode for the auction submodule /// @param baseToken Token provided by seller. Declared as an address to avoid dependency hell. /// @param quoteToken Token to accept as payment. Declared as an address to avoid dependency hell. /// @param curator (optional) Address of the proposed curator /// @param referrerFee (optional) Percent of bid/purchase amount received paid to a referrer in basis points, i.e. 1% = 100. /// @param callbacks (optional) Callbacks implementation for extended functionality /// @param callbackData (optional) abi-encoded data to be sent to the onCreate callback function /// @param derivativeType (optional) Derivative type, represented by the Keycode for the derivative submodule /// @param derivativeParams (optional) abi-encoded data to be used to create payout derivatives on a purchase. The format of this is dependent on the derivative module. /// @param wrapDerivative (optional) Whether to wrap the derivative in a ERC20 token instead of the native ERC6909 format struct RoutingParams { Keycode auctionType; address baseToken; address quoteToken; address curator; uint48 referrerFee; ICallback callbacks; bytes callbackData; Keycode derivativeType; bytes derivativeParams; bool wrapDerivative; } /// @notice Auction routing information for a lot /// /// @param seller Lot seller /// @param baseToken ERC20 token provided by seller /// @param quoteToken ERC20 token to accept as payment /// @param auctionReference Auction module, represented by its Veecode /// @param funding The amount of base tokens in funding remaining /// @param callbacks (optional) Callbacks implementation for extended functionality /// @param derivativeReference (optional) Derivative module, represented by its Veecode /// @param wrapDerivative (optional) Whether to wrap the derivative in a ERC20 token instead of the native ERC6909 format /// @param derivativeParams (optional) abi-encoded data to be used to create payout derivatives on a purchase struct Routing { address seller; // 20 bytes address baseToken; // 20 bytes address quoteToken; // 20 bytes Veecode auctionReference; // 7 bytes uint256 funding; // 32 bytes ICallback callbacks; // 20 bytes Veecode derivativeReference; // 7 bytes bool wrapDerivative; // 1 byte bytes derivativeParams; } /// @notice Fee information for a lot /// @dev This is split into a separate struct, otherwise the Routing struct would be too large /// and would throw a "stack too deep" error. /// /// Fee information is set at the time of auction creation, in order to prevent subsequent inflation. /// The fees are cached in order to prevent: /// - Reducing the amount of base tokens available for payout to the winning bidders /// - Reducing the amount of quote tokens available for payment to the seller /// /// @param curator Address of the proposed curator /// @param curated Whether the curator has approved the auction /// @param curatorFee The fee charged by the curator /// @param protocolFee The fee charged by the protocol /// @param referrerFee The fee charged by the referrer struct FeeData { address curator; // 20 bytes bool curated; // 1 byte uint48 curatorFee; // 6 bytes uint48 protocolFee; // 6 bytes uint48 referrerFee; // 6 bytes } // ========== AUCTION MANAGEMENT ========== // /// @notice Creates a new auction lot /// /// @param routing_ Routing information for the auction lot /// @param params_ Auction parameters for the auction lot /// @param infoHash_ IPFS hash of the auction information /// @return lotId ID of the auction lot function auction( RoutingParams calldata routing_, IAuction.AuctionParams calldata params_, string calldata infoHash_ ) external returns (uint96 lotId); /// @notice Cancels an auction lot /// /// @param lotId_ ID of the auction lot /// @param callbackData_ (optional) abi-encoded data to be sent to the onCancel callback function function cancel(uint96 lotId_, bytes calldata callbackData_) external; /// @notice Accept curation request for a lot. /// @notice If the curator wishes to charge a fee, it must be set before this function is called. /// @notice Access controlled. Must be proposed curator for lot. /// /// @param lotId_ Lot ID /// @param callbackData_ (optional) abi-encoded data to be sent to the onCurate callback function function curate(uint96 lotId_, bytes calldata callbackData_) external; // ========== AUCTION INFORMATION ========== // /// @notice The counter tracks the total number of auction lots function lotCounter() external view returns (uint96 lotCount); /// @notice Mapping of lot IDs to their routing information /// @dev See the `Routing` struct for more information /// /// @param lotId ID of the auction lot function lotRouting( uint96 lotId ) external view returns ( address seller, address baseToken, address quoteToken, Veecode auctionReference, uint256 funding, ICallback callbacks, Veecode derivativeReference, bool wrapDerivative, bytes memory derivativeParams ); /// @notice Mapping of lot IDs to their fee information /// @dev See the `FeeData` struct for more information /// /// @param lotId ID of the auction lot function lotFees( uint96 lotId ) external view returns ( address curator, bool curated, uint48 curatorFee, uint48 protocolFee, uint48 referrerFee ); /// @notice Mapping auction and derivative references to the condenser that is used to pass data between them /// /// @param auctionRef Versioned keycode for the auction module /// @param derivativeRef Versioned keycode for the derivative module /// @return condenserRef Versioned keycode for the condenser module function condensers( Veecode auctionRef, Veecode derivativeRef ) external view returns (Veecode condenserRef); /// @notice Gets the auction module for a given lot ID /// /// @param lotId_ ID of the auction lot /// @return module The auction module function getAuctionModuleForId(uint96 lotId_) external view returns (IAuction module); /// @notice Gets the derivative module for a given lot ID /// @dev Will revert if the lot does not have a derivative module /// /// @param lotId_ ID of the auction lot /// @return module The derivative module function getDerivativeModuleForId(uint96 lotId_) external view returns (IDerivative module); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC1271 standard signature validation method for * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. * * _Available since v4.1._ */ interface IERC1271 { /** * @dev Should return whether the signature provided is valid for the provided data * @param hash Hash of the data to be signed * @param signature Signature byte array associated with _data */ function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity >=0.8.0; /// @title IAuction /// @notice Interface for all auction modules used in the Axis AuctionHouse /// @dev This contract defines the external functions and data that are required for an auction module to be installed in an AuctionHouse. /// /// The implementing contract should define the following additional areas: /// - Any un-implemented functions /// - State variables for storage and configuration /// /// Data storage: /// - Each auction lot will have common data that is stored using the `Lot` struct. Inheriting auction modules may store additional data outside of the struct. interface IAuction { // ========== ERRORS ========== // error Auction_LotNotActive(uint96 lotId); error Auction_LotActive(uint96 lotId); error Auction_InvalidStart(uint48 start_, uint48 minimum_); error Auction_InvalidDuration(uint48 duration_, uint48 minimum_); error Auction_InvalidLotId(uint96 lotId); error Auction_OnlyLotOwner(); error Auction_AmountLessThanMinimum(); error Auction_InvalidParams(); error Auction_NotAuthorized(); error Auction_NotImplemented(); error Auction_InsufficientCapacity(); error Auction_LotNotConcluded(uint96 lotId); // ========== DATA STRUCTURES ========== // /// @notice Types of auctions enum AuctionType { Atomic, Batch } /// @notice Parameters when creating an auction lot /// /// @param start The timestamp when the auction starts /// @param duration The duration of the auction (in seconds) /// @param capacityInQuote Whether or not the capacity is in quote tokens /// @param capacity The capacity of the lot /// @param implParams Abi-encoded implementation-specific parameters struct AuctionParams { uint48 start; uint48 duration; bool capacityInQuote; uint256 capacity; bytes implParams; } /// @notice Core data for an auction lot /// /// @param start The timestamp when the auction starts /// @param conclusion The timestamp when the auction ends /// @param quoteTokenDecimals The quote token decimals /// @param baseTokenDecimals The base token decimals /// @param capacityInQuote Whether or not the capacity is in quote tokens /// @param capacity The capacity of the lot /// @param sold The amount of base tokens sold /// @param purchased The amount of quote tokens purchased struct Lot { uint48 start; // 6 + uint48 conclusion; // 6 + uint8 quoteTokenDecimals; // 1 + uint8 baseTokenDecimals; // 1 + bool capacityInQuote; // 1 = 15 - end of slot 1 uint256 capacity; // 32 - slot 2 uint256 sold; // 32 - slot 3 uint256 purchased; // 32 - slot 4 } // ========== STATE VARIABLES ========== // /// @notice Minimum auction duration in seconds function minAuctionDuration() external view returns (uint48); /// @notice General information pertaining to auction lots /// @dev See the `Lot` struct for more information on the return values /// /// @param lotId The lot ID function lotData( uint96 lotId ) external view returns ( uint48 start, uint48 conclusion, uint8 quoteTokenDecimals, uint8 baseTokenDecimals, bool capacityInQuote, uint256 capacity, uint256 sold, uint256 purchased ); // ========== AUCTION MANAGEMENT ========== // /// @notice Create an auction lot /// @dev The implementing function should handle the following: /// - Validate the lot parameters /// - Store the lot data /// /// @param lotId_ The lot id /// @param params_ The auction parameters /// @param quoteTokenDecimals_ The quote token decimals /// @param baseTokenDecimals_ The base token decimals function auction( uint96 lotId_, AuctionParams memory params_, uint8 quoteTokenDecimals_, uint8 baseTokenDecimals_ ) external; /// @notice Cancel an auction lot /// @dev The implementing function should handle the following: /// - Validate the lot parameters /// - Update the lot data /// /// @param lotId_ The lot id function cancelAuction(uint96 lotId_) external; // ========== AUCTION INFORMATION ========== // /// @notice Returns whether the auction is currently accepting bids or purchases /// @dev The implementing function should handle the following: /// - Return true if the lot is accepting bids/purchases /// - Return false if the lot has ended, been cancelled, or not started yet /// /// @param lotId_ The lot id /// @return bool Whether or not the lot is active function isLive(uint96 lotId_) external view returns (bool); /// @notice Returns whether the auction is upcoming /// @dev The implementing function should handle the following: /// - Return true if the lot has not started yet AND has not been cancelled /// - Return false if the lot is active, has ended, or was cancelled /// /// @param lotId_ The lot id /// @return bool Whether or not the lot is upcoming function isUpcoming(uint96 lotId_) external view returns (bool); /// @notice Returns whether the auction has ended /// @dev The implementing function should handle the following: /// - Return true if the lot is not accepting bids/purchases and will not at any point /// - Return false if the lot hasn't started or is actively accepting bids/purchases /// /// @param lotId_ The lot id /// @return bool Whether or not the lot is active function hasEnded(uint96 lotId_) external view returns (bool); /// @notice Get the remaining capacity of a lot /// @dev The implementing function should handle the following: /// - Return the remaining capacity of the lot /// /// @param lotId_ The lot id /// @return uint96 The remaining capacity of the lot function remainingCapacity(uint96 lotId_) external view returns (uint256); /// @notice Get whether or not the capacity is in quote tokens /// @dev The implementing function should handle the following: /// - Return true if the capacity is in quote tokens /// - Return false if the capacity is in base tokens /// /// @param lotId_ The lot id /// @return bool Whether or not the capacity is in quote tokens function capacityInQuote(uint96 lotId_) external view returns (bool); /// @notice Get the lot data for a given lot ID /// /// @param lotId_ The lot ID function getLot(uint96 lotId_) external view returns (Lot memory); /// @notice Get the auction type function auctionType() external view returns (AuctionType); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; /// @title ICallback /// @notice Interface for callback contracts use in the Axis system interface ICallback { /// @notice Callback configuration. Used by AuctionHouse to know which functions are implemented on this contract. /// @dev 8-bit map of which callbacks are implemented on this contract. /// The last two bits designate whether the callback should be expected send base tokens and receive quote tokens. /// If the contract does not send/receive, then the AuctionHouse will expect the tokens to be sent/received directly by the seller wallet. /// Bit 1: onCreate /// Bit 2: onCancel /// Bit 3: onCurate /// Bit 4: onPurchase /// Bit 5: onBid /// Bit 6: onSettle /// Bit 7: Receives quote tokens /// Bit 8: Sends base tokens (and receives them if refunded) // General functions that can be used by all auctions /// @notice Called when an auction is created. Reverts if validation fails. /// @dev The implementing function should: /// - Register the lot ID on the Callback contract /// - Validate that the seller is allowed to use the Callback contract /// /// @param lotId The ID of the lot /// @param seller The address of the seller /// @param baseToken The address of the base token /// @param quoteToken The address of the quote token /// @param capacity The capacity of the auction /// @param preFund If true, the calling contract expects base tokens to be sent to it /// @param callbackData Custom data provided by the seller function onCreate( uint96 lotId, address seller, address baseToken, address quoteToken, uint256 capacity, bool preFund, bytes calldata callbackData ) external returns (bytes4); /// @notice Called when an auction is cancelled. /// @dev If the Callback is configured to receive tokens and the auction was prefunded, then the refund will be sent prior to the call. /// /// @param lotId The ID of the lot /// @param refund The refund amount /// @param preFunded If true, the calling contract will have sent base tokens prior to the call /// @param callbackData Custom data provided by the seller function onCancel( uint96 lotId, uint256 refund, bool preFunded, bytes calldata callbackData ) external returns (bytes4); /// @notice Called when curate is called for an auction. /// /// @param lotId The ID of the lot /// @param curatorFee The curator fee payout /// @param preFund If true, the calling contract expects base tokens to be sent to it /// @param callbackData Custom data provided by the seller function onCurate( uint96 lotId, uint256 curatorFee, bool preFund, bytes calldata callbackData ) external returns (bytes4); // Atomic Auction hooks /// @notice Called when a buyer purchases from an atomic auction. Reverts if validation fails. /// @dev If the Callback is configured to receive quote tokens, then the user purchase amount of quote tokens will be sent prior to this call. /// If the Callback is configured to send base tokens, then the AuctionHouse will expect the payout of base tokens to be sent back. /// /// @param lotId The ID of the lot /// @param buyer The address of the buyer /// @param amount The amount of quote tokens purchased /// @param payout The amount of base tokens to receive /// @param preFunded If true, the calling contract has already been provided the base tokens. Otherwise, they must be provided. /// @param callbackData Custom data provided by the buyer function onPurchase( uint96 lotId, address buyer, uint256 amount, uint256 payout, bool preFunded, bytes calldata callbackData ) external returns (bytes4); // Batch Auction hooks /// @notice Called when a buyer bids on a batch auction. Reverts if validation fails. /// /// @param lotId The ID of the lot /// @param bidId The ID of the bid /// @param buyer The address of the buyer /// @param amount The amount of quote tokens bid /// @param callbackData Custom data provided by the buyer function onBid( uint96 lotId, uint64 bidId, address buyer, uint256 amount, bytes calldata callbackData ) external returns (bytes4); /// @notice Called when a batch auction is settled. /// @dev If the Callback is configured to receive tokens, then the proceeds and/or refund will be sent prior to the call. /// /// @param lotId The ID of the lot /// @param proceeds The proceeds amount /// @param refund The refund amount /// @param callbackData Custom data provided by the seller function onSettle( uint96 lotId, uint256 proceeds, uint256 refund, bytes calldata callbackData ) external returns (bytes4); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity >=0.8.0; /// @title IDerivative /// @notice Interface for Derivative functionality /// @dev Derivatives provide a mechanism to create synthetic assets that are backed by collateral, such as base tokens from an auction. interface IDerivative { // ========== ERRORS ========== // error Derivative_NotImplemented(); // ========== DATA STRUCTURES ========== // /// @notice Metadata for a derivative token /// /// @param exists True if the token has been deployed /// @param wrapped Non-zero if an ERC20-wrapped derivative has been deployed /// @param underlyingToken The address of the underlying token /// @param supply The total supply of the derivative token /// @param data Implementation-specific data struct Token { bool exists; address wrapped; address underlyingToken; uint256 supply; bytes data; } // ========== STATE VARIABLES ========== // /// @notice The metadata for a derivative token /// /// @param tokenId The ID of the derivative token /// @return exists True if the token has been deployed /// @return wrapped Non-zero if an ERC20-wrapped derivative has been deployed /// @return underlyingToken The address of the underlying token /// @return supply The total supply of the derivative token /// @return data Implementation-specific data function tokenMetadata( uint256 tokenId ) external view returns ( bool exists, address wrapped, address underlyingToken, uint256 supply, bytes memory data ); // ========== DERIVATIVE MANAGEMENT ========== // /// @notice Deploy a new derivative token. Optionally, deploys an ERC20 wrapper for composability. /// /// @param underlyingToken_ The address of the underlying token /// @param params_ ABI-encoded parameters for the derivative to be created /// @param wrapped_ Whether (true) or not (false) the derivative should be wrapped in an ERC20 token for composability /// @return tokenId_ The ID of the newly created derivative token /// @return wrappedAddress_ The address of the ERC20 wrapped derivative token, if wrapped_ is true, otherwise, it's the zero address. function deploy( address underlyingToken_, bytes memory params_, bool wrapped_ ) external returns (uint256 tokenId_, address wrappedAddress_); /// @notice Mint new derivative tokens. /// @notice Deploys the derivative token if it does not already exist. /// @notice The module is expected to transfer the collateral token to itself. /// /// @param to_ The address to mint the derivative tokens to /// @param underlyingToken_ The address of the underlying token /// @param params_ ABI-encoded parameters for the derivative to be created /// @param amount_ The amount of derivative tokens to create /// @param wrapped_ Whether (true) or not (false) the derivative should be wrapped in an ERC20 token for composability /// @return tokenId_ The ID of the newly created derivative token /// @return wrappedAddress_ The address of the ERC20 wrapped derivative token, if wrapped_ is true, otherwise, it's the zero address. /// @return amountCreated_ The amount of derivative tokens created function mint( address to_, address underlyingToken_, bytes memory params_, uint256 amount_, bool wrapped_ ) external returns (uint256 tokenId_, address wrappedAddress_, uint256 amountCreated_); /// @notice Mint new derivative tokens for a specific token ID /// /// @param to_ The address to mint the derivative tokens to /// @param tokenId_ The ID of the derivative token /// @param amount_ The amount of derivative tokens to create /// @param wrapped_ Whether (true) or not (false) the derivative should be wrapped in an ERC20 token for composability /// @return tokenId_ The ID of the derivative token /// @return wrappedAddress_ The address of the ERC20 wrapped derivative token, if wrapped_ is true, otherwise, it's the zero address. /// @return amountCreated_ The amount of derivative tokens created function mint( address to_, uint256 tokenId_, uint256 amount_, bool wrapped_ ) external returns (uint256, address, uint256); /// @notice Redeem all available derivative tokens for underlying collateral /// /// @param tokenId_ The ID of the derivative token to redeem function redeemMax(uint256 tokenId_) external; /// @notice Redeem derivative tokens for underlying collateral /// /// @param tokenId_ The ID of the derivative token to redeem /// @param amount_ The amount of derivative tokens to redeem function redeem(uint256 tokenId_, uint256 amount_) external; /// @notice Determines the amount of redeemable tokens for a given derivative token /// /// @param owner_ The owner of the derivative token /// @param tokenId_ The ID of the derivative token /// @return amount The amount of redeemable tokens function redeemable(address owner_, uint256 tokenId_) external view returns (uint256 amount); /// @notice Exercise a conversion of the derivative token per the specific implementation logic /// @dev Used for options or other derivatives with convertible options, e.g. Rage vesting. /// /// @param tokenId_ The ID of the derivative token to exercise /// @param amount The amount of derivative tokens to exercise function exercise(uint256 tokenId_, uint256 amount) external; /// @notice Determines the cost to exercise a derivative token in the quoted token /// @dev Used for options or other derivatives with convertible options, e.g. Rage vesting. /// /// @param tokenId_ The ID of the derivative token to exercise /// @param amount The amount of derivative tokens to exercise /// @return cost The cost to exercise the derivative token function exerciseCost(uint256 tokenId_, uint256 amount) external view returns (uint256 cost); /// @notice Reclaim posted collateral for a derivative token which can no longer be exercised /// @notice Access controlled: only callable by the derivative issuer via the auction house. /// /// @param tokenId_ The ID of the derivative token to reclaim function reclaim(uint256 tokenId_) external; /// @notice Transforms an existing derivative issued by this contract into something else. Derivative is burned and collateral sent to the auction house. /// @notice Access controlled: only callable by the auction house. /// /// @param tokenId_ The ID of the derivative token to transform /// @param from_ The address of the owner of the derivative token /// @param amount_ The amount of derivative tokens to transform function transform(uint256 tokenId_, address from_, uint256 amount_) external; /// @notice Wrap an existing derivative into an ERC20 token for composability /// Deploys the ERC20 wrapper if it does not already exist /// /// @param tokenId_ The ID of the derivative token to wrap /// @param amount_ The amount of derivative tokens to wrap function wrap(uint256 tokenId_, uint256 amount_) external; /// @notice Unwrap an ERC20 derivative token into the underlying ERC6909 derivative /// /// @param tokenId_ The ID of the derivative token to unwrap /// @param amount_ The amount of derivative tokens to unwrap function unwrap(uint256 tokenId_, uint256 amount_) external; /// @notice Validate derivative params for the specific implementation /// The parameters should be the same as what is passed into `deploy()` or `mint()` /// /// @param underlyingToken_ The address of the underlying token /// @param params_ The params to validate /// @return isValid Whether or not the params are valid function validate( address underlyingToken_, bytes memory params_ ) external view returns (bool isValid); // ========== DERIVATIVE INFORMATION ========== // /// @notice Compute a unique token ID, given the parameters for the derivative /// /// @param underlyingToken_ The address of the underlying token /// @param params_ The parameters for the derivative /// @return tokenId The unique token ID function computeId( address underlyingToken_, bytes memory params_ ) external pure returns (uint256 tokenId); /// @notice Get the metadata for a derivative token /// /// @param tokenId The ID of the derivative token /// @return tokenData The metadata for the derivative token function getTokenMetadata(uint256 tokenId) external view returns (Token memory tokenData); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity >=0.8.19; // Inspired by Default framework keycode management of dependencies and based on the Modules pattern /// @notice 5 byte/character identifier for the Module /// @dev 3-5 characters from A-Z type Keycode is bytes5; /// @notice 7 byte identifier for the Module, including version /// @dev 2 characters from 0-9 (a version number), followed by Keycode type Veecode is bytes7; error InvalidVeecode(Veecode veecode_); function toKeycode(bytes5 keycode_) pure returns (Keycode) { return Keycode.wrap(keycode_); } function fromKeycode(Keycode keycode_) pure returns (bytes5) { return Keycode.unwrap(keycode_); } // solhint-disable-next-line func-visibility function wrapVeecode(Keycode keycode_, uint8 version_) pure returns (Veecode) { // Get the digits of the version bytes1 firstDigit = bytes1(version_ / 10 + 0x30); bytes1 secondDigit = bytes1((version_ % 10) + 0x30); // Pack everything and wrap as a Veecode return Veecode.wrap(bytes7(abi.encodePacked(firstDigit, secondDigit, keycode_))); } // solhint-disable-next-line func-visibility function toVeecode(bytes7 veecode_) pure returns (Veecode) { return Veecode.wrap(veecode_); } // solhint-disable-next-line func-visibility function fromVeecode(Veecode veecode_) pure returns (bytes7) { return Veecode.unwrap(veecode_); } function unwrapVeecode(Veecode veecode_) pure returns (Keycode, uint8) { bytes7 unwrapped = Veecode.unwrap(veecode_); // Get the version from the first 2 bytes if (unwrapped[0] < 0x30 || unwrapped[0] > 0x39 || unwrapped[1] < 0x30 || unwrapped[1] > 0x39) { revert InvalidVeecode(veecode_); } uint8 version = (uint8(unwrapped[0]) - 0x30) * 10; version += uint8(unwrapped[1]) - 0x30; // Get the Keycode by shifting the full Veecode to the left by 2 bytes Keycode keycode = Keycode.wrap(bytes5(unwrapped << 16)); return (keycode, version); } function keycodeFromVeecode(Veecode veecode_) pure returns (Keycode) { (Keycode keycode,) = unwrapVeecode(veecode_); return keycode; } // solhint-disable-next-line func-visibility function ensureValidVeecode(Veecode veecode_) pure { bytes7 unwrapped = Veecode.unwrap(veecode_); for (uint256 i; i < 7;) { bytes1 char = unwrapped[i]; if (i < 2) { // First 2 characters must be the version, each character is a number 0-9 if (char < 0x30 || char > 0x39) revert InvalidVeecode(veecode_); } else if (i < 5) { // Next 3 characters after the first 3 can be A-Z if (char < 0x41 || char > 0x5A) revert InvalidVeecode(veecode_); } else { // Last 2 character must be A-Z or blank if (char != 0x00 && (char < 0x41 || char > 0x5A)) revert InvalidVeecode(veecode_); } unchecked { i++; } } // Check that the version is not 0 // This is because the version is by default 0 if the module is not installed (, uint8 moduleVersion) = unwrapVeecode(veecode_); if (moduleVersion == 0) revert InvalidVeecode(veecode_); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
{ "remappings": [ "@forge-std/=dependencies/forge-std-1.9.4/src/", "@openzeppelin/=dependencies/@openzeppelin-contracts-4.9.6/", "@axis-core/=dependencies/axis-core-1.0.1/src/", "@clones-with-immutable-args-1.1.1/=dependencies/axis-core-1.0.1/dependencies/clones-with-immutable-args-1.1.1/src/", "@forge-std-1.9.1/=dependencies/axis-core-1.0.1/dependencies/forge-std-1.9.1/src/", "@openzeppelin-contracts-4.9.2/=dependencies/axis-core-1.0.1/dependencies/@openzeppelin-contracts-4.9.2/", "@openzeppelin-contracts-4.9.6/=dependencies/@openzeppelin-contracts-4.9.6/", "@solady-0.0.124/=dependencies/axis-core-1.0.1/dependencies/solady-0.0.124/src/", "@solmate-6.7.0/=dependencies/axis-core-1.0.1/dependencies/solmate-6.7.0/src/", "axis-core-1.0.1/=dependencies/axis-core-1.0.1/src/", "forge-std-1.9.4/=dependencies/forge-std-1.9.4/src/", "forge-std/=lib/forge-std/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
Contract ABI
API[{"inputs":[{"internalType":"address","name":"serviceSigner_","type":"address"},{"internalType":"address[]","name":"auctionHouses_","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyAssigned","type":"error"},{"inputs":[{"internalType":"string","name":"param","type":"string"}],"name":"InvalidParam","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"auctionHouse","type":"address"},{"indexed":false,"internalType":"uint96","name":"lotId","type":"uint96"},{"indexed":false,"internalType":"string","name":"ipfsCID","type":"string"}],"name":"AuctionRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"curator","type":"address"},{"indexed":false,"internalType":"uint256","name":"xId","type":"uint256"},{"indexed":false,"internalType":"string","name":"ipfsCID","type":"string"}],"name":"CuratorRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"xId","type":"uint256"},{"indexed":false,"internalType":"string","name":"ipfsCID","type":"string"}],"name":"CuratorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"auctionHouse_","type":"address"}],"name":"addAuctionHouse","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"xId_","type":"uint256"},{"internalType":"address","name":"curator_","type":"address"}],"name":"addCuratorAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"auctionHouse","type":"address"},{"internalType":"uint96","name":"lotId","type":"uint96"}],"name":"auctionMetadata","outputs":[{"internalType":"string","name":"ipfsCID","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"curator","type":"address"}],"name":"curatorId","outputs":[{"internalType":"uint256","name":"xId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"xId","type":"uint256"}],"name":"curatorMetadata","outputs":[{"internalType":"string","name":"ipfsCID","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"curator","type":"address"},{"internalType":"uint256","name":"xId","type":"uint256"},{"internalType":"string","name":"ipfsCID","type":"string"}],"internalType":"struct AxisMetadataRegistry.CuratorRegistration","name":"payload_","type":"tuple"}],"name":"getDigest","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAuctionHouse","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signer_","type":"address"},{"components":[{"internalType":"address","name":"curator","type":"address"},{"internalType":"uint256","name":"xId","type":"uint256"},{"internalType":"string","name":"ipfsCID","type":"string"}],"internalType":"struct AxisMetadataRegistry.CuratorRegistration","name":"payload_","type":"tuple"},{"internalType":"bytes","name":"signature_","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"auctionHouse_","type":"address"},{"internalType":"uint96","name":"lotId_","type":"uint96"},{"internalType":"string","name":"ipfsCID_","type":"string"}],"name":"registerAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"curator","type":"address"},{"internalType":"uint256","name":"xId","type":"uint256"},{"internalType":"string","name":"ipfsCID","type":"string"}],"internalType":"struct AxisMetadataRegistry.CuratorRegistration","name":"payload_","type":"tuple"},{"internalType":"bytes","name":"signature_","type":"bytes"}],"name":"registerCurator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"auctionHouse_","type":"address"}],"name":"removeAuctionHouse","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"xId_","type":"uint256"},{"internalType":"address","name":"curator_","type":"address"}],"name":"removeCuratorAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"serviceSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"xId_","type":"uint256"},{"internalType":"string","name":"ipfsCID_","type":"string"}],"name":"updateCurator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateDomainSeparator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"serviceSigner_","type":"address"}],"name":"updateServiceSigner","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162001b4938038062001b49833981016040819052620000349162000159565b6200003f33620000d6565b60005b8151811015620000ae5760016004600084848151811062000067576200006762000242565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580620000a58162000258565b91505062000042565b5050600380546001600160a01b0319166001600160a01b039290921691909117905562000280565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200013e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200016d57600080fd5b620001788362000126565b602084810151919350906001600160401b03808211156200019857600080fd5b818601915086601f830112620001ad57600080fd5b815181811115620001c257620001c262000143565b8060051b604051601f19603f83011681018181108582111715620001ea57620001ea62000143565b6040529182528482019250838101850191898311156200020957600080fd5b938501935b828510156200023257620002228562000126565b845293850193928501926200020e565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b6000600182016200027957634e487b7160e01b600052601160045260246000fd5b5060010190565b6118b980620002906000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806382a7576b116100b85780639a8a05921161007c5780639a8a05921461028c578063d212b5d314610295578063d7bcf546146102a8578063efed64be146102c8578063f2fde38b146102db578063faf8dbfb146102ee57600080fd5b806382a7576b1461022657806389ccfe89146102395780638da5cb5b1461024157806390eff5c414610266578063936525071461027957600080fd5b80634372ff85116100ff5780634372ff85146101c25780634f011a65146101d55780636704126f146101e8578063715018a6146101fb57806376e63bb01461020357600080fd5b806318cb9c1d1461013c57806320e4ff85146101515780632dd372e61461017957806331995fda1461018c5780633644e515146101ac575b600080fd5b61014f61014a366004611108565b610301565b005b61016461015f366004611192565b6103ab565b60405190151581526020015b60405180910390f35b61014f61018736600461120b565b6103ff565b61019f61019a366004611244565b610429565b60405161017091906112c2565b6101b46104ce565b604051908152602001610170565b61014f6101d036600461120b565b6104ed565b61014f6101e33660046112d5565b610519565b61014f6101f636600461133e565b610729565b61014f61099e565b61016461021136600461120b565b60046020526000908152604090205460ff1681565b61014f610234366004611108565b6109b2565b61014f610a6f565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610170565b6101b4610274366004611397565b610ad1565b61014f6102873660046113d4565b610bba565b6101b460015481565b60035461024e906001600160a01b031681565b6101b46102b636600461120b565b60056020526000908152604090205481565b61019f6102d6366004611413565b610c93565b61014f6102e936600461120b565b610cac565b61014f6102fc36600461120b565b610d25565b8160000361032b57604051634389d5ab60e01b81526004016103229061142c565b60405180910390fd5b33600090815260056020526040902054821461035a5760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b0381166000908152600560205260409020541561039157604051639688dc5160e01b815260040160405180910390fd5b6001600160a01b0316600090815260056020526040902055565b60006103f6856103ba86610ad1565b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610d4e92505050565b95945050505050565b610407610daf565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60076020908152600092835260408084209091529082529020805461044d90611449565b80601f016020809104026020016040519081016040528092919081815260200182805461047990611449565b80156104c65780601f1061049b576101008083540402835291602001916104c6565b820191906000526020600020905b8154815290600101906020018083116104a957829003601f168201915b505050505081565b600060015446146104e6576104e1610e09565b905090565b5060025490565b6104f5610daf565b6001600160a01b03166000908152600460205260409020805460ff19166001179055565b610526602084018461120b565b6001600160a01b0316336001600160a01b0316146105575760405163ea8e4eb560e01b815260040160405180910390fd5b826020013560000361059a57604051634389d5ab60e01b815260206004820152600b60248201526a1c185e5b1bd8590b9e125960aa1b6044820152606401610322565b600560006105ab602086018661120b565b6001600160a01b03168152602081019190915260400160002054156105e357604051639688dc5160e01b815260040160405180910390fd5b6105f0604084018461147d565b905060000361063457604051634389d5ab60e01b815260206004820152600f60248201526e1c185e5b1bd8590b9a5c199cd0d251608a1b6044820152606401610322565b60035461064c906001600160a01b03168484846103ab565b61066957604051638baa579f60e01b815260040160405180910390fd5b60208301803590600590600090610680908761120b565b6001600160a01b0316815260208101919091526040908101600020919091556106ab9084018461147d565b6020808601356000908152600690915260409020916106cb919083611529565b507f8d71b236876fe8aa8294fe7f3c63662bfc3fc1a240fdbe49488b37f3366958fc6106fa602085018561120b565b602085013561070c604087018761147d565b60405161071c9493929190611613565b60405180910390a1505050565b6001600160a01b03841660009081526004602052604090205460ff1661078157604051634389d5ab60e01b815260206004820152600c60248201526b61756374696f6e486f75736560a01b6044820152606401610322565b6000849050806001600160a01b031663c4ce88fd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e8919061163b565b6001600160601b0316846001600160601b03161061083157604051634389d5ab60e01b81526020600482015260056024820152641b1bdd125960da1b6044820152606401610322565b604051634f17001d60e11b81526001600160601b03851660048201526000906001600160a01b03831690639e2e003a90602401600060405180830381865afa158015610881573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108a991908101906116f3565b50505050505050509050806001600160a01b0316336001600160a01b0316146108e55760405163ea8e4eb560e01b815260040160405180910390fd5b600083900361092157604051634389d5ab60e01b81526020600482015260076024820152661a5c199cd0d25160ca1b6044820152606401610322565b6001600160a01b03861660009081526007602090815260408083206001600160601b03891684529091529020610958848683611529565b507f18b40f4816934f1a7bd5ff51d87f48d9ddacbd7653b2cde31a904cbd3c30b5248686868660405161098e94939291906117c1565b60405180910390a1505050505050565b6109a6610daf565b6109b06000610eae565b565b816000036109d357604051634389d5ab60e01b81526004016103229061142c565b336000908152600560205260409020548214610a025760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b0381166000908152600560205260409020548214610a5457604051634389d5ab60e01b815260206004820152600760248201526631bab930ba37b960c91b6044820152606401610322565b6001600160a01b031660009081526005602052604081205550565b6001544603610ac05760405162461bcd60e51b815260206004820181905260248201527f444f4d41494e5f534550415241544f525f414c52454144595f555044415445446044820152606401610322565b46600155610acc610e09565b600255565b6000610adb6104ce565b7f1378000983868b9cd38cd6c7408ceb9051309140ca9bff5d199043ae5649938c610b09602085018561120b565b6020850135610b1b604087018761147d565b604051610b299291906117f5565b604051908190038120610b60949392916020019384526001600160a01b039290921660208401526040830152606082015260800190565b60405160208183030381529060405280519060200120604051602001610b9d92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b82600003610bdb57604051634389d5ab60e01b81526004016103229061142c565b336000908152600560205260409020548314610c0a5760405163ea8e4eb560e01b815260040160405180910390fd5b6000819003610c4657604051634389d5ab60e01b81526020600482015260076024820152661a5c199cd0d25160ca1b6044820152606401610322565b6000838152600660205260409020610c5f828483611529565b507f8d48f79a76a920c2d4e03ef6f1c031c427129a9bd429bb36523fc25cc1e4ea6883838360405161071c93929190611805565b6006602052600090815260409020805461044d90611449565b610cb4610daf565b6001600160a01b038116610d195760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610322565b610d2281610eae565b50565b610d2d610daf565b6001600160a01b03166000908152600460205260409020805460ff19169055565b6000806000610d5d8585610efe565b90925090506000816004811115610d7657610d7661181f565b148015610d945750856001600160a01b0316826001600160a01b0316145b80610da55750610da5868686610f43565b9695505050505050565b6000546001600160a01b031633146109b05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610322565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f4873d266cc369576c1140f197e29f2f69e4e0a34e63dac384a5a61ccd6762dbb918101919091527f15124d26d1272f8d4d5266a24ca397811f414b8cd05a53b26b745f63af5ae2fc60608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000808251604103610f345760208301516040840151606085015160001a610f288782858561102f565b94509450505050610f3c565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401610f6d929190611835565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610fab919061184e565b600060405180830381855afa9150503d8060008114610fe6576040519150601f19603f3d011682016040523d82523d6000602084013e610feb565b606091505b5091509150818015610fff57506020815110155b8015610da557508051630b135d3f60e11b90611024908301602090810190840161186a565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561106657506000905060036110ea565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156110ba573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166110e3576000600192509250506110ea565b9150600090505b94509492505050565b6001600160a01b0381168114610d2257600080fd5b6000806040838503121561111b57600080fd5b82359150602083013561112d816110f3565b809150509250929050565b60006060828403121561114a57600080fd5b50919050565b60008083601f84011261116257600080fd5b50813567ffffffffffffffff81111561117a57600080fd5b602083019150836020828501011115610f3c57600080fd5b600080600080606085870312156111a857600080fd5b84356111b3816110f3565b9350602085013567ffffffffffffffff808211156111d057600080fd5b6111dc88838901611138565b945060408701359150808211156111f257600080fd5b506111ff87828801611150565b95989497509550505050565b60006020828403121561121d57600080fd5b8135611228816110f3565b9392505050565b6001600160601b0381168114610d2257600080fd5b6000806040838503121561125757600080fd5b8235611262816110f3565b9150602083013561112d8161122f565b60005b8381101561128d578181015183820152602001611275565b50506000910152565b600081518084526112ae816020860160208601611272565b601f01601f19169290920160200192915050565b6020815260006112286020830184611296565b6000806000604084860312156112ea57600080fd5b833567ffffffffffffffff8082111561130257600080fd5b61130e87838801611138565b9450602086013591508082111561132457600080fd5b5061133186828701611150565b9497909650939450505050565b6000806000806060858703121561135457600080fd5b843561135f816110f3565b9350602085013561136f8161122f565b9250604085013567ffffffffffffffff81111561138b57600080fd5b6111ff87828801611150565b6000602082840312156113a957600080fd5b813567ffffffffffffffff8111156113c057600080fd5b6113cc84828501611138565b949350505050565b6000806000604084860312156113e957600080fd5b83359250602084013567ffffffffffffffff81111561140757600080fd5b61133186828701611150565b60006020828403121561142557600080fd5b5035919050565b6020808252600390820152621e125960ea1b604082015260600190565b600181811c9082168061145d57607f821691505b60208210810361114a57634e487b7160e01b600052602260045260246000fd5b6000808335601e1984360301811261149457600080fd5b83018035915067ffffffffffffffff8211156114af57600080fd5b602001915036819003821315610f3c57600080fd5b634e487b7160e01b600052604160045260246000fd5b601f82111561152457600081815260208120601f850160051c810160208610156115015750805b601f850160051c820191505b818110156115205782815560010161150d565b5050505b505050565b67ffffffffffffffff831115611541576115416114c4565b6115558361154f8354611449565b836114da565b6000601f84116001811461158957600085156115715750838201355b600019600387901b1c1916600186901b1783556115e3565b600083815260209020601f19861690835b828110156115ba578685013582556020948501946001909201910161159a565b50868210156115d75760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b0385168152836020820152606060408201526000610da56060830184866115ea565b60006020828403121561164d57600080fd5b81516112288161122f565b80516001600160c81b03198116811461167057600080fd5b919050565b600082601f83011261168657600080fd5b815167ffffffffffffffff808211156116a1576116a16114c4565b604051601f8301601f19908116603f011681019082821181831017156116c9576116c96114c4565b816040528381528660208588010111156116e257600080fd5b610da5846020830160208901611272565b60008060008060008060008060006101208a8c03121561171257600080fd5b895161171d816110f3565b60208b015190995061172e816110f3565b60408b015190985061173f816110f3565b965061174d60608b01611658565b955060808a0151945060a08a0151611764816110f3565b935061177260c08b01611658565b925060e08a0151801515811461178757600080fd5b6101008b015190925067ffffffffffffffff8111156117a557600080fd5b6117b18c828d01611675565b9150509295985092959850929598565b6001600160a01b03851681526001600160601b0384166020820152606060408201819052600090610da590830184866115ea565b8183823760009101908152919050565b8381526040602082015260006103f66040830184866115ea565b634e487b7160e01b600052602160045260246000fd5b8281526040602082015260006113cc6040830184611296565b60008251611860818460208701611272565b9190910192915050565b60006020828403121561187c57600080fd5b505191905056fea2646970667358221220c46037ef2a22106778ef28d541adf8fede783729a5f6b79ee15a9eb975d873fe64736f6c63430008130033000000000000000000000000b47c8e4beb28af80ede5e5bf474927b110ef2c0e00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ba0000c28179ce533233a943d432eddd154e62a3
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101375760003560e01c806382a7576b116100b85780639a8a05921161007c5780639a8a05921461028c578063d212b5d314610295578063d7bcf546146102a8578063efed64be146102c8578063f2fde38b146102db578063faf8dbfb146102ee57600080fd5b806382a7576b1461022657806389ccfe89146102395780638da5cb5b1461024157806390eff5c414610266578063936525071461027957600080fd5b80634372ff85116100ff5780634372ff85146101c25780634f011a65146101d55780636704126f146101e8578063715018a6146101fb57806376e63bb01461020357600080fd5b806318cb9c1d1461013c57806320e4ff85146101515780632dd372e61461017957806331995fda1461018c5780633644e515146101ac575b600080fd5b61014f61014a366004611108565b610301565b005b61016461015f366004611192565b6103ab565b60405190151581526020015b60405180910390f35b61014f61018736600461120b565b6103ff565b61019f61019a366004611244565b610429565b60405161017091906112c2565b6101b46104ce565b604051908152602001610170565b61014f6101d036600461120b565b6104ed565b61014f6101e33660046112d5565b610519565b61014f6101f636600461133e565b610729565b61014f61099e565b61016461021136600461120b565b60046020526000908152604090205460ff1681565b61014f610234366004611108565b6109b2565b61014f610a6f565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610170565b6101b4610274366004611397565b610ad1565b61014f6102873660046113d4565b610bba565b6101b460015481565b60035461024e906001600160a01b031681565b6101b46102b636600461120b565b60056020526000908152604090205481565b61019f6102d6366004611413565b610c93565b61014f6102e936600461120b565b610cac565b61014f6102fc36600461120b565b610d25565b8160000361032b57604051634389d5ab60e01b81526004016103229061142c565b60405180910390fd5b33600090815260056020526040902054821461035a5760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b0381166000908152600560205260409020541561039157604051639688dc5160e01b815260040160405180910390fd5b6001600160a01b0316600090815260056020526040902055565b60006103f6856103ba86610ad1565b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610d4e92505050565b95945050505050565b610407610daf565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60076020908152600092835260408084209091529082529020805461044d90611449565b80601f016020809104026020016040519081016040528092919081815260200182805461047990611449565b80156104c65780601f1061049b576101008083540402835291602001916104c6565b820191906000526020600020905b8154815290600101906020018083116104a957829003601f168201915b505050505081565b600060015446146104e6576104e1610e09565b905090565b5060025490565b6104f5610daf565b6001600160a01b03166000908152600460205260409020805460ff19166001179055565b610526602084018461120b565b6001600160a01b0316336001600160a01b0316146105575760405163ea8e4eb560e01b815260040160405180910390fd5b826020013560000361059a57604051634389d5ab60e01b815260206004820152600b60248201526a1c185e5b1bd8590b9e125960aa1b6044820152606401610322565b600560006105ab602086018661120b565b6001600160a01b03168152602081019190915260400160002054156105e357604051639688dc5160e01b815260040160405180910390fd5b6105f0604084018461147d565b905060000361063457604051634389d5ab60e01b815260206004820152600f60248201526e1c185e5b1bd8590b9a5c199cd0d251608a1b6044820152606401610322565b60035461064c906001600160a01b03168484846103ab565b61066957604051638baa579f60e01b815260040160405180910390fd5b60208301803590600590600090610680908761120b565b6001600160a01b0316815260208101919091526040908101600020919091556106ab9084018461147d565b6020808601356000908152600690915260409020916106cb919083611529565b507f8d71b236876fe8aa8294fe7f3c63662bfc3fc1a240fdbe49488b37f3366958fc6106fa602085018561120b565b602085013561070c604087018761147d565b60405161071c9493929190611613565b60405180910390a1505050565b6001600160a01b03841660009081526004602052604090205460ff1661078157604051634389d5ab60e01b815260206004820152600c60248201526b61756374696f6e486f75736560a01b6044820152606401610322565b6000849050806001600160a01b031663c4ce88fd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e8919061163b565b6001600160601b0316846001600160601b03161061083157604051634389d5ab60e01b81526020600482015260056024820152641b1bdd125960da1b6044820152606401610322565b604051634f17001d60e11b81526001600160601b03851660048201526000906001600160a01b03831690639e2e003a90602401600060405180830381865afa158015610881573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108a991908101906116f3565b50505050505050509050806001600160a01b0316336001600160a01b0316146108e55760405163ea8e4eb560e01b815260040160405180910390fd5b600083900361092157604051634389d5ab60e01b81526020600482015260076024820152661a5c199cd0d25160ca1b6044820152606401610322565b6001600160a01b03861660009081526007602090815260408083206001600160601b03891684529091529020610958848683611529565b507f18b40f4816934f1a7bd5ff51d87f48d9ddacbd7653b2cde31a904cbd3c30b5248686868660405161098e94939291906117c1565b60405180910390a1505050505050565b6109a6610daf565b6109b06000610eae565b565b816000036109d357604051634389d5ab60e01b81526004016103229061142c565b336000908152600560205260409020548214610a025760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b0381166000908152600560205260409020548214610a5457604051634389d5ab60e01b815260206004820152600760248201526631bab930ba37b960c91b6044820152606401610322565b6001600160a01b031660009081526005602052604081205550565b6001544603610ac05760405162461bcd60e51b815260206004820181905260248201527f444f4d41494e5f534550415241544f525f414c52454144595f555044415445446044820152606401610322565b46600155610acc610e09565b600255565b6000610adb6104ce565b7f1378000983868b9cd38cd6c7408ceb9051309140ca9bff5d199043ae5649938c610b09602085018561120b565b6020850135610b1b604087018761147d565b604051610b299291906117f5565b604051908190038120610b60949392916020019384526001600160a01b039290921660208401526040830152606082015260800190565b60405160208183030381529060405280519060200120604051602001610b9d92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050919050565b82600003610bdb57604051634389d5ab60e01b81526004016103229061142c565b336000908152600560205260409020548314610c0a5760405163ea8e4eb560e01b815260040160405180910390fd5b6000819003610c4657604051634389d5ab60e01b81526020600482015260076024820152661a5c199cd0d25160ca1b6044820152606401610322565b6000838152600660205260409020610c5f828483611529565b507f8d48f79a76a920c2d4e03ef6f1c031c427129a9bd429bb36523fc25cc1e4ea6883838360405161071c93929190611805565b6006602052600090815260409020805461044d90611449565b610cb4610daf565b6001600160a01b038116610d195760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610322565b610d2281610eae565b50565b610d2d610daf565b6001600160a01b03166000908152600460205260409020805460ff19169055565b6000806000610d5d8585610efe565b90925090506000816004811115610d7657610d7661181f565b148015610d945750856001600160a01b0316826001600160a01b0316145b80610da55750610da5868686610f43565b9695505050505050565b6000546001600160a01b031633146109b05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610322565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f4873d266cc369576c1140f197e29f2f69e4e0a34e63dac384a5a61ccd6762dbb918101919091527f15124d26d1272f8d4d5266a24ca397811f414b8cd05a53b26b745f63af5ae2fc60608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000808251604103610f345760208301516040840151606085015160001a610f288782858561102f565b94509450505050610f3c565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401610f6d929190611835565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610fab919061184e565b600060405180830381855afa9150503d8060008114610fe6576040519150601f19603f3d011682016040523d82523d6000602084013e610feb565b606091505b5091509150818015610fff57506020815110155b8015610da557508051630b135d3f60e11b90611024908301602090810190840161186a565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561106657506000905060036110ea565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156110ba573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166110e3576000600192509250506110ea565b9150600090505b94509492505050565b6001600160a01b0381168114610d2257600080fd5b6000806040838503121561111b57600080fd5b82359150602083013561112d816110f3565b809150509250929050565b60006060828403121561114a57600080fd5b50919050565b60008083601f84011261116257600080fd5b50813567ffffffffffffffff81111561117a57600080fd5b602083019150836020828501011115610f3c57600080fd5b600080600080606085870312156111a857600080fd5b84356111b3816110f3565b9350602085013567ffffffffffffffff808211156111d057600080fd5b6111dc88838901611138565b945060408701359150808211156111f257600080fd5b506111ff87828801611150565b95989497509550505050565b60006020828403121561121d57600080fd5b8135611228816110f3565b9392505050565b6001600160601b0381168114610d2257600080fd5b6000806040838503121561125757600080fd5b8235611262816110f3565b9150602083013561112d8161122f565b60005b8381101561128d578181015183820152602001611275565b50506000910152565b600081518084526112ae816020860160208601611272565b601f01601f19169290920160200192915050565b6020815260006112286020830184611296565b6000806000604084860312156112ea57600080fd5b833567ffffffffffffffff8082111561130257600080fd5b61130e87838801611138565b9450602086013591508082111561132457600080fd5b5061133186828701611150565b9497909650939450505050565b6000806000806060858703121561135457600080fd5b843561135f816110f3565b9350602085013561136f8161122f565b9250604085013567ffffffffffffffff81111561138b57600080fd5b6111ff87828801611150565b6000602082840312156113a957600080fd5b813567ffffffffffffffff8111156113c057600080fd5b6113cc84828501611138565b949350505050565b6000806000604084860312156113e957600080fd5b83359250602084013567ffffffffffffffff81111561140757600080fd5b61133186828701611150565b60006020828403121561142557600080fd5b5035919050565b6020808252600390820152621e125960ea1b604082015260600190565b600181811c9082168061145d57607f821691505b60208210810361114a57634e487b7160e01b600052602260045260246000fd5b6000808335601e1984360301811261149457600080fd5b83018035915067ffffffffffffffff8211156114af57600080fd5b602001915036819003821315610f3c57600080fd5b634e487b7160e01b600052604160045260246000fd5b601f82111561152457600081815260208120601f850160051c810160208610156115015750805b601f850160051c820191505b818110156115205782815560010161150d565b5050505b505050565b67ffffffffffffffff831115611541576115416114c4565b6115558361154f8354611449565b836114da565b6000601f84116001811461158957600085156115715750838201355b600019600387901b1c1916600186901b1783556115e3565b600083815260209020601f19861690835b828110156115ba578685013582556020948501946001909201910161159a565b50868210156115d75760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b0385168152836020820152606060408201526000610da56060830184866115ea565b60006020828403121561164d57600080fd5b81516112288161122f565b80516001600160c81b03198116811461167057600080fd5b919050565b600082601f83011261168657600080fd5b815167ffffffffffffffff808211156116a1576116a16114c4565b604051601f8301601f19908116603f011681019082821181831017156116c9576116c96114c4565b816040528381528660208588010111156116e257600080fd5b610da5846020830160208901611272565b60008060008060008060008060006101208a8c03121561171257600080fd5b895161171d816110f3565b60208b015190995061172e816110f3565b60408b015190985061173f816110f3565b965061174d60608b01611658565b955060808a0151945060a08a0151611764816110f3565b935061177260c08b01611658565b925060e08a0151801515811461178757600080fd5b6101008b015190925067ffffffffffffffff8111156117a557600080fd5b6117b18c828d01611675565b9150509295985092959850929598565b6001600160a01b03851681526001600160601b0384166020820152606060408201819052600090610da590830184866115ea565b8183823760009101908152919050565b8381526040602082015260006103f66040830184866115ea565b634e487b7160e01b600052602160045260246000fd5b8281526040602082015260006113cc6040830184611296565b60008251611860818460208701611272565b9190910192915050565b60006020828403121561187c57600080fd5b505191905056fea2646970667358221220c46037ef2a22106778ef28d541adf8fede783729a5f6b79ee15a9eb975d873fe64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b47c8e4beb28af80ede5e5bf474927b110ef2c0e00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ba0000c28179ce533233a943d432eddd154e62a3
-----Decoded View---------------
Arg [0] : serviceSigner_ (address): 0xB47C8e4bEb28af80eDe5E5bF474927b110Ef2c0e
Arg [1] : auctionHouses_ (address[]): 0xBA0000c28179CE533233a943d432eddD154E62A3
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000b47c8e4beb28af80ede5e5bf474927b110ef2c0e
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [3] : 000000000000000000000000ba0000c28179ce533233a943d432eddd154e62a3
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.