Source Code
Overview
S Balance
0 S
Token Holdings
More Info
ContractCreator
Latest 25 from a total of 80 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Execute Applicat... | 15244008 | 4 days ago | IN | 0 S | 0.00307234 | ||||
Propose Agent | 15243999 | 4 days ago | IN | 0 S | 0.0002867 | ||||
Execute Applicat... | 15240835 | 4 days ago | IN | 0 S | 0.00307234 | ||||
Propose Agent | 15240826 | 4 days ago | IN | 0 S | 0.0002867 | ||||
Execute Applicat... | 15240487 | 4 days ago | IN | 0 S | 0.00309115 | ||||
Propose Agent | 15240478 | 4 days ago | IN | 0 S | 0.00023751 | ||||
Set Token Tax Pa... | 15240461 | 4 days ago | IN | 0 S | 0.00004043 | ||||
Set Token Supply... | 15240454 | 4 days ago | IN | 0 S | 0.00006372 | ||||
Propose Agent | 15239472 | 4 days ago | IN | 0 S | 0.00023751 | ||||
Set Token Tax Pa... | 15239459 | 4 days ago | IN | 0 S | 0.00004043 | ||||
Set Token Supply... | 15239450 | 4 days ago | IN | 0 S | 0.00004866 | ||||
Set Application ... | 15239192 | 4 days ago | IN | 0 S | 0.00003314 | ||||
Propose Agent | 15239083 | 4 days ago | IN | 0 S | 0.00023751 | ||||
Set Token Tax Pa... | 15239070 | 4 days ago | IN | 0 S | 0.00004967 | ||||
Set Token Supply... | 15239063 | 4 days ago | IN | 0 S | 0.00006406 | ||||
Propose Agent | 15238871 | 4 days ago | IN | 0 S | 0.00023751 | ||||
Set Token Tax Pa... | 15238856 | 4 days ago | IN | 0 S | 0.00004045 | ||||
Set Token Supply... | 15238848 | 4 days ago | IN | 0 S | 0.0000641 | ||||
Propose Agent | 15238695 | 4 days ago | IN | 0 S | 0.00023751 | ||||
Set Token Tax Pa... | 15238681 | 4 days ago | IN | 0 S | 0.00004045 | ||||
Set Token Supply... | 15238672 | 4 days ago | IN | 0 S | 0.00006412 | ||||
Propose Agent | 15238525 | 4 days ago | IN | 0 S | 0.00023751 | ||||
Set Token Tax Pa... | 15238512 | 4 days ago | IN | 0 S | 0.00004045 | ||||
Set Token Supply... | 15238504 | 4 days ago | IN | 0 S | 0.00005185 | ||||
Propose Agent | 15238209 | 4 days ago | IN | 0 S | 0.00023751 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
15244008 | 4 days ago | 0 S | ||||
15244008 | 4 days ago | 0 S | ||||
15244008 | 4 days ago | 0 S | ||||
15244008 | 4 days ago | 0 S | ||||
15244008 | 4 days ago | Contract Creation | 0 S | |||
15243999 | 4 days ago | 0 S | ||||
15243999 | 4 days ago | 0 S | ||||
15243999 | 4 days ago | 0 S | ||||
15240835 | 4 days ago | 0 S | ||||
15240835 | 4 days ago | 0 S | ||||
15240835 | 4 days ago | 0 S | ||||
15240835 | 4 days ago | 0 S | ||||
15240835 | 4 days ago | Contract Creation | 0 S | |||
15240826 | 4 days ago | 0 S | ||||
15240826 | 4 days ago | 0 S | ||||
15240826 | 4 days ago | 0 S | ||||
15240487 | 4 days ago | 0 S | ||||
15240487 | 4 days ago | 0 S | ||||
15240487 | 4 days ago | 0 S | ||||
15240487 | 4 days ago | 0 S | ||||
15240487 | 4 days ago | Contract Creation | 0 S | |||
15240478 | 4 days ago | 0 S | ||||
15240478 | 4 days ago | 0 S | ||||
15240478 | 4 days ago | 0 S | ||||
15239472 | 4 days ago | 0 S |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
TheFactory
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/proxy/Clones.sol"; import "@openzeppelin/contracts/governance/IGovernor.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; // import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; // import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; // import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; // import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol"; import "@openzeppelin/contracts/utils/Pausable.sol"; import "./ITheFactory.sol"; import "./virtuals/IAgentToken.sol"; // import "./IAgentVeToken.sol"; // import "./IAgentDAO.sol"; // import "./IAgentNft.sol"; // import "./libs/IERC6551Registry.sol"; import "./interfaces/IUniswapV2Factory.sol"; import "./interfaces/IUniswapV2Router02.sol"; contract TheFactory is ITheFactory, Initializable, // AccessControlUpgradeable, AccessControl, // PausableUpgradeable Pausable { using SafeERC20 for IERC20; uint256 private _nextId; address public tokenImplementation; // address public daoImplementation; // address public nft; // address public tbaRegistry; // Token bound account uint256 public applicationThreshold; address[] public allTokens; // address[] public allDAOs; address public assetToken; // Base currency uint256 public maturityDuration; // Staking duration in seconds for initial LP. eg: 10years bytes32 public constant WITHDRAW_ROLE = keccak256("WITHDRAW_ROLE"); // Able to withdraw and execute applications event NewPersona( uint256 virtualId, address token, // address dao, // address tba, // address veToken, address lp ); event NewApplication(uint256 id); enum ApplicationStatus { Active, Executed, Withdrawn } struct Application { string name; string symbol; string tokenURI; ApplicationStatus status; uint256 withdrawableAmount; address proposer; uint8[] cores; // uint256 proposalEndBlock; // uint256 virtualId; // bytes32 tbaSalt; // address tbaImplementation; // uint32 daoVotingPeriod; // uint256 daoThreshold; } mapping(uint256 => Application) private _applications; event ApplicationThresholdUpdated(uint256 newThreshold); // event GovUpdated(address newGov); // event ImplContractsUpdated(address token, address dao); // address private _vault; // Vault to hold all Virtual NFTs bool internal locked; modifier noReentrant() { require(!locked, "cannot reenter"); locked = true; _; locked = false; } /////////////////////////////////////////////////////////////// // V2 Storage /////////////////////////////////////////////////////////////// address[] public allTradingTokens; address private _uniswapRouter; // address public veTokenImplementation; address private _tokenAdmin; // address public defaultDelegatee; // Default agent token params bytes private _tokenSupplyParams; bytes private _tokenTaxParams; /////////////////////////////////////////////////////////////// // V4 Storage /////////////////////////////////////////////////////////////// // The follow 2 variables maps only custom ERC20 to agent applications // mapping(address => uint256) private _tokenApplication; // mapping(uint256 => address) private _applicationToken; /////////////////////////////////////////////////////////////// // /// @custom:oz-upgrades-unsafe-allow constructor // constructor() { // // _disableInitializers(); // } function initialize( address tokenImplementation_, // address veTokenImplementation_, // address daoImplementation_, // address tbaRegistry_, // address nft_, // uint256 applicationThreshold_, // address vault_, uint256 nextId_, address assetToken_ ) public initializer { // __Pausable_init(); // __AccessControl_init(); tokenImplementation = tokenImplementation_; // veTokenImplementation = veTokenImplementation_; // daoImplementation = daoImplementation_; assetToken = assetToken_; // tbaRegistry = tbaRegistry_; // nft = nft_; // applicationThreshold = applicationThreshold_; _nextId = nextId_; // _nextId = 0; _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); // _vault = vault_; } function getApplication( uint256 proposalId ) public view returns (Application memory) { return _applications[proposalId]; } function proposeAgent( string memory name, string memory symbol, string memory tokenURI, uint8[] memory cores // , // bytes32 tbaSalt, // address tbaImplementation, // uint32 daoVotingPeriod, // uint256 daoThreshold ) public whenNotPaused returns (uint256) { address sender = _msgSender(); require( IERC20(assetToken).balanceOf(sender) >= applicationThreshold, "Insufficient asset token" ); require( IERC20(assetToken).allowance(sender, address(this)) >= applicationThreshold, "Insufficient asset token allowance" ); require(cores.length > 0, "Cores must be provided"); IERC20(assetToken).safeTransferFrom( sender, address(this), applicationThreshold ); uint256 id = _nextId++; // uint256 proposalEndBlock = block.number; // No longer required in v2 Application memory application = Application( name, symbol, tokenURI, ApplicationStatus.Active, applicationThreshold, sender, cores // , // proposalEndBlock // , // 0, // tbaSalt, // tbaImplementation, // daoVotingPeriod, // daoThreshold ); _applications[id] = application; emit NewApplication(id); return id; } function withdraw(uint256 id) public noReentrant { Application storage application = _applications[id]; require( msg.sender == application.proposer || hasRole(WITHDRAW_ROLE, msg.sender), "Not proposer" ); require( application.status == ApplicationStatus.Active, "Application is not active" ); // require( // block.number > application.proposalEndBlock, // "Application is not matured yet" // ); uint256 withdrawableAmount = application.withdrawableAmount; application.withdrawableAmount = 0; application.status = ApplicationStatus.Withdrawn; IERC20(assetToken).safeTransfer( application.proposer, withdrawableAmount ); // address customToken = _applicationToken[id]; // if (customToken != address(0)) { // IERC20(customToken).safeTransfer( // application.proposer, // IERC20(customToken).balanceOf(address(this)) // ); // _tokenApplication[customToken] = 0; // _applicationToken[id] = address(0); // } } function _executeApplication( uint256 id, bool canStake, bytes memory tokenSupplyParams_ ) internal { require( _applications[id].status == ApplicationStatus.Active, "Application is not active" ); require(_tokenAdmin != address(0), "Token admin not set"); Application storage application = _applications[id]; uint256 initialAmount = application.withdrawableAmount; application.withdrawableAmount = 0; application.status = ApplicationStatus.Executed; // C1 & C2 address token = address(0); // token = _applicationToken[id]; address lp = address(0); // if (token == address(0)) { token = _createNewAgentToken( application.name, application.symbol, tokenSupplyParams_ ); lp = IAgentToken(token).liquidityPools()[0]; IERC20(assetToken).safeTransfer(token, initialAmount); IAgentToken(token).addInitialLiquidity(address(this)); // } else { // // Custom token // lp = _createPair(token); // IERC20(token).forceApprove(_uniswapRouter, type(uint256).max); // IERC20(assetToken).forceApprove(_uniswapRouter, initialAmount); // // Add the liquidity: // IUniswapV2Router02(_uniswapRouter).addLiquidity( // token, // assetToken, // IERC20(token).balanceOf(address(this)), // initialAmount, // 0, // 0, // address(this), // block.timestamp // ); // } // // C3 // address veToken = _createNewAgentVeToken( // string.concat("Staked ", application.name), // string.concat("s", application.symbol), // lp, // application.proposer, // canStake // ); // // C4 // string memory daoName = string.concat(application.name, " DAO"); // address payable dao = payable( // _createNewDAO( // daoName, // IVotes(veToken), // application.daoVotingPeriod, // application.daoThreshold // ) // ); // // C5 // uint256 virtualId = IAgentNft(nft).nextVirtualId(); // IAgentNft(nft).mint( // virtualId, // _vault, // application.tokenURI, // dao, // application.proposer, // application.cores, // lp, // token // ); // application.virtualId = virtualId; // // C6 // uint256 chainId; // assembly { // chainId := chainid() // } // address tbaAddress = IERC6551Registry(tbaRegistry).createAccount( // application.tbaImplementation, // application.tbaSalt, // chainId, // nft, // virtualId // ); // IAgentNft(nft).setTBA(virtualId, tbaAddress); // // C7 // IERC20(lp).approve(veToken, type(uint256).max); // IAgentVeToken(veToken).stake( // IERC20(lp).balanceOf(address(this)), // application.proposer, // defaultDelegatee // ); // emit NewPersona(virtualId, token, dao, tbaAddress, veToken, lp); // emit NewPersona(virtualId, token, lp); } function executeApplication(uint256 id, bool canStake) public noReentrant { // This will bootstrap an Agent with following components: // C1: Agent Token // C2: LP Pool + Initial liquidity // C3: Agent veToken // C4: Agent DAO // C5: Agent NFT // C6: TBA // C7: Stake liquidity token to get veToken Application storage application = _applications[id]; require( msg.sender == application.proposer || hasRole(WITHDRAW_ROLE, msg.sender), "Not proposer" ); _executeApplication(id, canStake, _tokenSupplyParams); } // function _createNewDAO( // string memory name, // IVotes token, // uint32 daoVotingPeriod, // uint256 daoThreshold // ) internal returns (address instance) { // instance = Clones.clone(daoImplementation); // IAgentDAO(instance).initialize( // name, // token, // nft, // daoThreshold, // daoVotingPeriod // ); // allDAOs.push(instance); // return instance; // } function _createNewAgentToken( string memory name, string memory symbol, bytes memory tokenSupplyParams_ ) internal returns (address instance) { instance = Clones.clone(tokenImplementation); IAgentToken(instance).initialize( [_tokenAdmin, _uniswapRouter, assetToken], abi.encode(name, symbol), tokenSupplyParams_, _tokenTaxParams ); allTradingTokens.push(instance); return instance; } // function _createNewAgentVeToken( // string memory name, // string memory symbol, // address stakingAsset, // address founder, // bool canStake // ) internal returns (address instance) { // instance = Clones.clone(veTokenImplementation); // IAgentVeToken(instance).initialize( // name, // symbol, // founder, // stakingAsset, // block.timestamp + maturityDuration, // address(nft), // canStake // ); // allTokens.push(instance); // return instance; // } function totalAgents() public view returns (uint256) { return allTokens.length; } function setApplicationThreshold( uint256 newThreshold ) public onlyRole(DEFAULT_ADMIN_ROLE) { applicationThreshold = newThreshold; emit ApplicationThresholdUpdated(newThreshold); } // function setVault(address newVault) public onlyRole(DEFAULT_ADMIN_ROLE) { // _vault = newVault; // } function setImplementations( // address veToken, // address dao, address token ) public onlyRole(DEFAULT_ADMIN_ROLE) { tokenImplementation = token; // daoImplementation = dao; // veTokenImplementation = veToken; } function setMaturityDuration( uint256 newDuration ) public onlyRole(DEFAULT_ADMIN_ROLE) { maturityDuration = newDuration; } function setUniswapRouter( address router ) public onlyRole(DEFAULT_ADMIN_ROLE) { _uniswapRouter = router; } function setTokenAdmin( address newTokenAdmin ) public onlyRole(DEFAULT_ADMIN_ROLE) { _tokenAdmin = newTokenAdmin; } function setTokenSupplyParams( uint256 maxSupply, uint256 lpSupply, uint256 vaultSupply, uint256 maxTokensPerWallet, uint256 maxTokensPerTxn, uint256 botProtectionDurationInSeconds, address vault ) public onlyRole(DEFAULT_ADMIN_ROLE) { _tokenSupplyParams = abi.encode( maxSupply, lpSupply, vaultSupply, maxTokensPerWallet, maxTokensPerTxn, botProtectionDurationInSeconds, vault ); } function setTokenTaxParams( uint256 projectBuyTaxBasisPoints, uint256 projectSellTaxBasisPoints, uint256 taxSwapThresholdBasisPoints, address projectTaxRecipient ) public onlyRole(DEFAULT_ADMIN_ROLE) { _tokenTaxParams = abi.encode( projectBuyTaxBasisPoints, projectSellTaxBasisPoints, taxSwapThresholdBasisPoints, projectTaxRecipient ); } function setAssetToken( address newToken ) public onlyRole(DEFAULT_ADMIN_ROLE) { assetToken = newToken; } function pause() public onlyRole(DEFAULT_ADMIN_ROLE) { _pause(); } function unpause() public onlyRole(DEFAULT_ADMIN_ROLE) { _unpause(); } // function _msgSender() // internal // view // // override(ContextUpgradeable) // returns (address sender) // { // sender = ContextUpgradeable._msgSender(); // } // function _msgData() // internal // view // // override(ContextUpgradeable) // returns (bytes calldata) // { // return ContextUpgradeable._msgData(); // } // function setDefaultDelegatee( // address newDelegatee // ) public onlyRole(DEFAULT_ADMIN_ROLE) { // defaultDelegatee = newDelegatee; // } // // Bootstrap Agent with existing ERC20 tokens // function initFromToken( // address tokenAddr, // uint8[] memory cores, // bytes32 tbaSalt, // address tbaImplementation, // uint32 daoVotingPeriod, // uint256 daoThreshold, // uint256 initialLP // ) public whenNotPaused returns (uint256) { // address sender = _msgSender(); // require(_tokenApplication[tokenAddr] == 0, "Token already exists"); // require(isCompatibleToken(tokenAddr), "Unsupported token"); // require( // IERC20(assetToken).balanceOf(sender) >= applicationThreshold, // "Insufficient asset token" // ); // require( // IERC20(assetToken).allowance(sender, address(this)) >= // applicationThreshold, // "Insufficient asset token allowance" // ); // require(cores.length > 0, "Cores must be provided"); // require(initialLP > 0, "InitialLP must be greater than 0"); // IERC20(tokenAddr).safeTransferFrom(sender, address(this), initialLP); // IERC20(assetToken).safeTransferFrom( // sender, // address(this), // applicationThreshold // ); // uint256 id = _nextId++; // _tokenApplication[tokenAddr] = id; // _applicationToken[id] = tokenAddr; // Application memory application = Application( // IAgentToken(tokenAddr).name(), // IAgentToken(tokenAddr).symbol(), // "", // ApplicationStatus.Active, // applicationThreshold, // sender, // cores, // block.number, // 0, // tbaSalt, // tbaImplementation, // daoVotingPeriod, // daoThreshold // ); // _applications[id] = application; // emit NewApplication(id); // return id; // } // function executeTokenApplication( // uint256 id, // bool canStake // ) public noReentrant { // // This will bootstrap an Agent with following components: // // C2: LP Pool + Initial liquidity // // C3: Agent veToken // // C4: Agent DAO // // C5: Agent NFT // // C6: TBA // // C7: Stake liquidity token to get veToken // Application storage application = _applications[id]; // require( // msg.sender == application.proposer || // hasRole(WITHDRAW_ROLE, msg.sender), // "Not proposer" // ); // require( // _applicationToken[id] != address(0), // "Not custom token application" // ); // _executeApplication(id, canStake, _tokenSupplyParams); // } // function isCompatibleToken(address tokenAddr) public view returns (bool) { // try IAgentToken(tokenAddr).name() returns (string memory) { // try IAgentToken(tokenAddr).symbol() returns (string memory) { // try IAgentToken(tokenAddr).totalSupply() returns (uint256) { // try // IAgentToken(tokenAddr).balanceOf(address(this)) // returns (uint256) { // return true; // } catch { // return false; // } // } catch { // return false; // } // } catch { // return false; // } // } catch { // return false; // } // } function _createPair( address tokenAddr ) internal returns (address uniswapV2Pair_) { IUniswapV2Factory factory = IUniswapV2Factory( IUniswapV2Router02(_uniswapRouter).factory() ); require( factory.getPair(tokenAddr, assetToken) == address(0), "pool already exists" ); uniswapV2Pair_ = factory.createPair(tokenAddr, assetToken); return (uniswapV2Pair_); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) pragma solidity ^0.8.20; import {IAccessControl} from "./IAccessControl.sol"; import {Context} from "../utils/Context.sol"; import {ERC165} from "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address account => bool) hasRole; bytes32 adminRole; } mapping(bytes32 role => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with an {AccessControlUnauthorizedAccount} error including the required role. */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual returns (bool) { return _roles[role].hasRole[account]; } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` * is missing `role`. */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert AccessControlUnauthorizedAccount(account, role); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address callerConfirmation) public virtual { if (callerConfirmation != _msgSender()) { revert AccessControlBadConfirmation(); } _revokeRole(role, callerConfirmation); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual returns (bool) { if (!hasRole(role, account)) { _roles[role].hasRole[account] = true; emit RoleGranted(role, account, _msgSender()); return true; } else { return false; } } /** * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { if (hasRole(role, account)) { _roles[role].hasRole[account] = false; emit RoleRevoked(role, account, _msgSender()); return true; } else { return false; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC-165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role). * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (governance/IGovernor.sol) pragma solidity ^0.8.20; import {IERC165} from "../interfaces/IERC165.sol"; import {IERC6372} from "../interfaces/IERC6372.sol"; /** * @dev Interface of the {Governor} core. * * NOTE: Event parameters lack the `indexed` keyword for compatibility with GovernorBravo events. * Making event parameters `indexed` affects how events are decoded, potentially breaking existing indexers. */ interface IGovernor is IERC165, IERC6372 { enum ProposalState { Pending, Active, Canceled, Defeated, Succeeded, Queued, Expired, Executed } /** * @dev Empty proposal or a mismatch between the parameters length for a proposal call. */ error GovernorInvalidProposalLength(uint256 targets, uint256 calldatas, uint256 values); /** * @dev The vote was already cast. */ error GovernorAlreadyCastVote(address voter); /** * @dev Token deposits are disabled in this contract. */ error GovernorDisabledDeposit(); /** * @dev The `account` is not a proposer. */ error GovernorOnlyProposer(address account); /** * @dev The `account` is not the governance executor. */ error GovernorOnlyExecutor(address account); /** * @dev The `proposalId` doesn't exist. */ error GovernorNonexistentProposal(uint256 proposalId); /** * @dev The current state of a proposal is not the required for performing an operation. * The `expectedStates` is a bitmap with the bits enabled for each ProposalState enum position * counting from right to left. * * NOTE: If `expectedState` is `bytes32(0)`, the proposal is expected to not be in any state (i.e. not exist). * This is the case when a proposal that is expected to be unset is already initiated (the proposal is duplicated). * * See {Governor-_encodeStateBitmap}. */ error GovernorUnexpectedProposalState(uint256 proposalId, ProposalState current, bytes32 expectedStates); /** * @dev The voting period set is not a valid period. */ error GovernorInvalidVotingPeriod(uint256 votingPeriod); /** * @dev The `proposer` does not have the required votes to create a proposal. */ error GovernorInsufficientProposerVotes(address proposer, uint256 votes, uint256 threshold); /** * @dev The `proposer` is not allowed to create a proposal. */ error GovernorRestrictedProposer(address proposer); /** * @dev The vote type used is not valid for the corresponding counting module. */ error GovernorInvalidVoteType(); /** * @dev The provided params buffer is not supported by the counting module. */ error GovernorInvalidVoteParams(); /** * @dev Queue operation is not implemented for this governor. Execute should be called directly. */ error GovernorQueueNotImplemented(); /** * @dev The proposal hasn't been queued yet. */ error GovernorNotQueuedProposal(uint256 proposalId); /** * @dev The proposal has already been queued. */ error GovernorAlreadyQueuedProposal(uint256 proposalId); /** * @dev The provided signature is not valid for the expected `voter`. * If the `voter` is a contract, the signature is not valid using {IERC1271-isValidSignature}. */ error GovernorInvalidSignature(address voter); /** * @dev Emitted when a proposal is created. */ event ProposalCreated( uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 voteStart, uint256 voteEnd, string description ); /** * @dev Emitted when a proposal is queued. */ event ProposalQueued(uint256 proposalId, uint256 etaSeconds); /** * @dev Emitted when a proposal is executed. */ event ProposalExecuted(uint256 proposalId); /** * @dev Emitted when a proposal is canceled. */ event ProposalCanceled(uint256 proposalId); /** * @dev Emitted when a vote is cast without params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. */ event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason); /** * @dev Emitted when a vote is cast with params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. * `params` are additional encoded parameters. Their interpretation also depends on the voting module used. */ event VoteCastWithParams( address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params ); /** * @notice module:core * @dev Name of the governor instance (used in building the EIP-712 domain separator). */ function name() external view returns (string memory); /** * @notice module:core * @dev Version of the governor instance (used in building the EIP-712 domain separator). Default: "1" */ function version() external view returns (string memory); /** * @notice module:voting * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`. * * There are 2 standard keys: `support` and `quorum`. * * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`. * - `quorum=bravo` means that only For votes are counted towards quorum. * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum. * * If a counting module makes use of encoded `params`, it should include this under a `params` key with a unique * name that describes the behavior. For example: * * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain. * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote. * * NOTE: The string can be decoded by the standard * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`] * JavaScript class. */ // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() external view returns (string memory); /** * @notice module:core * @dev Hashing function used to (re)build the proposal id from the proposal details.. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) external pure returns (uint256); /** * @notice module:core * @dev Current state of a proposal, following Compound's convention */ function state(uint256 proposalId) external view returns (ProposalState); /** * @notice module:core * @dev The number of votes required in order for a voter to become a proposer. */ function proposalThreshold() external view returns (uint256); /** * @notice module:core * @dev Timepoint used to retrieve user's votes and quorum. If using block number (as per Compound's Comp), the * snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the * following block. */ function proposalSnapshot(uint256 proposalId) external view returns (uint256); /** * @notice module:core * @dev Timepoint at which votes close. If using block number, votes close at the end of this block, so it is * possible to cast a vote during this block. */ function proposalDeadline(uint256 proposalId) external view returns (uint256); /** * @notice module:core * @dev The account that created a proposal. */ function proposalProposer(uint256 proposalId) external view returns (address); /** * @notice module:core * @dev The time when a queued proposal becomes executable ("ETA"). Unlike {proposalSnapshot} and * {proposalDeadline}, this doesn't use the governor clock, and instead relies on the executor's clock which may be * different. In most cases this will be a timestamp. */ function proposalEta(uint256 proposalId) external view returns (uint256); /** * @notice module:core * @dev Whether a proposal needs to be queued before execution. */ function proposalNeedsQueuing(uint256 proposalId) external view returns (bool); /** * @notice module:user-config * @dev Delay, between the proposal is created and the vote starts. The unit this duration is expressed in depends * on the clock (see ERC-6372) this contract uses. * * This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a * proposal starts. * * NOTE: While this interface returns a uint256, timepoints are stored as uint48 following the ERC-6372 clock type. * Consequently this value must fit in a uint48 (when added to the current clock). See {IERC6372-clock}. */ function votingDelay() external view returns (uint256); /** * @notice module:user-config * @dev Delay between the vote start and vote end. The unit this duration is expressed in depends on the clock * (see ERC-6372) this contract uses. * * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting * duration compared to the voting delay. * * NOTE: This value is stored when the proposal is submitted so that possible changes to the value do not affect * proposals that have already been submitted. The type used to save it is a uint32. Consequently, while this * interface returns a uint256, the value it returns should fit in a uint32. */ function votingPeriod() external view returns (uint256); /** * @notice module:user-config * @dev Minimum number of cast voted required for a proposal to be successful. * * NOTE: The `timepoint` parameter corresponds to the snapshot used for counting vote. This allows to scale the * quorum depending on values such as the totalSupply of a token at this timepoint (see {ERC20Votes}). */ function quorum(uint256 timepoint) external view returns (uint256); /** * @notice module:reputation * @dev Voting power of an `account` at a specific `timepoint`. * * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or * multiple), {ERC20Votes} tokens. */ function getVotes(address account, uint256 timepoint) external view returns (uint256); /** * @notice module:reputation * @dev Voting power of an `account` at a specific `timepoint` given additional encoded parameters. */ function getVotesWithParams( address account, uint256 timepoint, bytes memory params ) external view returns (uint256); /** * @notice module:voting * @dev Returns whether `account` has cast a vote on `proposalId`. */ function hasVoted(uint256 proposalId, address account) external view returns (bool); /** * @dev Create a new proposal. Vote start after a delay specified by {IGovernor-votingDelay} and lasts for a * duration specified by {IGovernor-votingPeriod}. * * Emits a {ProposalCreated} event. * * NOTE: The state of the Governor and `targets` may change between the proposal creation and its execution. * This may be the result of third party actions on the targeted contracts, or other governor proposals. * For example, the balance of this contract could be updated or its access control permissions may be modified, * possibly compromising the proposal's ability to execute successfully (e.g. the governor doesn't have enough * value to cover a proposal with multiple transfers). */ function propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) external returns (uint256 proposalId); /** * @dev Queue a proposal. Some governors require this step to be performed before execution can happen. If queuing * is not necessary, this function may revert. * Queuing a proposal requires the quorum to be reached, the vote to be successful, and the deadline to be reached. * * Emits a {ProposalQueued} event. */ function queue( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) external returns (uint256 proposalId); /** * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the * deadline to be reached. Depending on the governor it might also be required that the proposal was queued and * that some delay passed. * * Emits a {ProposalExecuted} event. * * NOTE: Some modules can modify the requirements for execution, for example by adding an additional timelock. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) external payable returns (uint256 proposalId); /** * @dev Cancel a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e. * before the vote starts. * * Emits a {ProposalCanceled} event. */ function cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) external returns (uint256 proposalId); /** * @dev Cast a vote * * Emits a {VoteCast} event. */ function castVote(uint256 proposalId, uint8 support) external returns (uint256 balance); /** * @dev Cast a vote with a reason * * Emits a {VoteCast} event. */ function castVoteWithReason( uint256 proposalId, uint8 support, string calldata reason ) external returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParams( uint256 proposalId, uint8 support, string calldata reason, bytes memory params ) external returns (uint256 balance); /** * @dev Cast a vote using the voter's signature, including ERC-1271 signature support. * * Emits a {VoteCast} event. */ function castVoteBySig( uint256 proposalId, uint8 support, address voter, bytes memory signature ) external returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters using the voter's signature, * including ERC-1271 signature support. * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, address voter, string calldata reason, bytes memory params, bytes memory signature ) external returns (uint256 balance); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC165} from "./IERC165.sol"; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC6372.sol) pragma solidity ^0.8.20; interface IERC6372 { /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() external view returns (uint48); /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.2.0) (proxy/Clones.sol) pragma solidity ^0.8.20; import {Create2} from "../utils/Create2.sol"; import {Errors} from "../utils/Errors.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-1167[ERC-1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. */ library Clones { error CloneArgumentsTooLong(); /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { return clone(implementation, 0); } /** * @dev Same as {xref-Clones-clone-address-}[clone], but with a `value` parameter to send native currency * to the new contract. * * NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory) * to always have enough balance for new deployments. Consider exposing this function under a payable method. */ function clone(address implementation, uint256 value) internal returns (address instance) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } assembly ("memory-safe") { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create(value, 0x09, 0x37) } if (instance == address(0)) { revert Errors.FailedDeployment(); } } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple times will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { return cloneDeterministic(implementation, salt, 0); } /** * @dev Same as {xref-Clones-cloneDeterministic-address-bytes32-}[cloneDeterministic], but with * a `value` parameter to send native currency to the new contract. * * NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory) * to always have enough balance for new deployments. Consider exposing this function under a payable method. */ function cloneDeterministic( address implementation, bytes32 salt, uint256 value ) internal returns (address instance) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } assembly ("memory-safe") { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create2(value, 0x09, 0x37, salt) } if (instance == address(0)) { revert Errors.FailedDeployment(); } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { assembly ("memory-safe") { let ptr := mload(0x40) mstore(add(ptr, 0x38), deployer) mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff) mstore(add(ptr, 0x14), implementation) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73) mstore(add(ptr, 0x58), salt) mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37)) predicted := and(keccak256(add(ptr, 0x43), 0x55), 0xffffffffffffffffffffffffffffffffffffffff) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt ) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } /** * @dev Deploys and returns the address of a clone that mimics the behavior of `implementation` with custom * immutable arguments. These are provided through `args` and cannot be changed after deployment. To * access the arguments within the implementation, use {fetchCloneArgs}. * * This function uses the create opcode, which should never revert. */ function cloneWithImmutableArgs(address implementation, bytes memory args) internal returns (address instance) { return cloneWithImmutableArgs(implementation, args, 0); } /** * @dev Same as {xref-Clones-cloneWithImmutableArgs-address-bytes-}[cloneWithImmutableArgs], but with a `value` * parameter to send native currency to the new contract. * * NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory) * to always have enough balance for new deployments. Consider exposing this function under a payable method. */ function cloneWithImmutableArgs( address implementation, bytes memory args, uint256 value ) internal returns (address instance) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args); assembly ("memory-safe") { instance := create(value, add(bytecode, 0x20), mload(bytecode)) } if (instance == address(0)) { revert Errors.FailedDeployment(); } } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation` with custom * immutable arguments. These are provided through `args` and cannot be changed after deployment. To * access the arguments within the implementation, use {fetchCloneArgs}. * * This function uses the create2 opcode and a `salt` to deterministically deploy the clone. Using the same * `implementation`, `args` and `salt` multiple times will revert, since the clones cannot be deployed twice * at the same address. */ function cloneDeterministicWithImmutableArgs( address implementation, bytes memory args, bytes32 salt ) internal returns (address instance) { return cloneDeterministicWithImmutableArgs(implementation, args, salt, 0); } /** * @dev Same as {xref-Clones-cloneDeterministicWithImmutableArgs-address-bytes-bytes32-}[cloneDeterministicWithImmutableArgs], * but with a `value` parameter to send native currency to the new contract. * * NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory) * to always have enough balance for new deployments. Consider exposing this function under a payable method. */ function cloneDeterministicWithImmutableArgs( address implementation, bytes memory args, bytes32 salt, uint256 value ) internal returns (address instance) { bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args); return Create2.deploy(value, salt, bytecode); } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}. */ function predictDeterministicAddressWithImmutableArgs( address implementation, bytes memory args, bytes32 salt, address deployer ) internal pure returns (address predicted) { bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args); return Create2.computeAddress(salt, keccak256(bytecode), deployer); } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}. */ function predictDeterministicAddressWithImmutableArgs( address implementation, bytes memory args, bytes32 salt ) internal view returns (address predicted) { return predictDeterministicAddressWithImmutableArgs(implementation, args, salt, address(this)); } /** * @dev Get the immutable args attached to a clone. * * - If `instance` is a clone that was deployed using `clone` or `cloneDeterministic`, this * function will return an empty array. * - If `instance` is a clone that was deployed using `cloneWithImmutableArgs` or * `cloneDeterministicWithImmutableArgs`, this function will return the args array used at * creation. * - If `instance` is NOT a clone deployed using this library, the behavior is undefined. This * function should only be used to check addresses that are known to be clones. */ function fetchCloneArgs(address instance) internal view returns (bytes memory) { bytes memory result = new bytes(instance.code.length - 45); // revert if length is too short assembly ("memory-safe") { extcodecopy(instance, add(result, 32), 45, mload(result)) } return result; } /** * @dev Helper that prepares the initcode of the proxy with immutable args. * * An assembly variant of this function requires copying the `args` array, which can be efficiently done using * `mcopy`. Unfortunately, that opcode is not available before cancun. A pure solidity implementation using * abi.encodePacked is more expensive but also more portable and easier to review. * * NOTE: https://eips.ethereum.org/EIPS/eip-170[EIP-170] limits the length of the contract code to 24576 bytes. * With the proxy code taking 45 bytes, that limits the length of the immutable args to 24531 bytes. */ function _cloneCodeWithImmutableArgs( address implementation, bytes memory args ) private pure returns (bytes memory) { if (args.length > 24531) revert CloneArgumentsTooLong(); return abi.encodePacked( hex"61", uint16(args.length + 45), hex"3d81600a3d39f3363d3d373d3d3d363d73", implementation, hex"5af43d82803e903d91602b57fd5bf3", args ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC1363} from "../../../interfaces/IERC1363.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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 v5.1.0) (utils/Create2.sol) pragma solidity ^0.8.20; import {Errors} from "./Errors.sol"; /** * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. * `CREATE2` can be used to compute in advance the address where a smart * contract will be deployed, which allows for interesting new mechanisms known * as 'counterfactual interactions'. * * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more * information. */ library Create2 { /** * @dev There's no code to deploy. */ error Create2EmptyBytecode(); /** * @dev Deploys a contract using `CREATE2`. The address where the contract * will be deployed can be known in advance via {computeAddress}. * * The bytecode for a contract can be obtained from Solidity with * `type(contractName).creationCode`. * * Requirements: * * - `bytecode` must not be empty. * - `salt` must have not been used for `bytecode` already. * - the factory must have a balance of at least `amount`. * - if `amount` is non-zero, `bytecode` must have a `payable` constructor. */ function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) { if (address(this).balance < amount) { revert Errors.InsufficientBalance(address(this).balance, amount); } if (bytecode.length == 0) { revert Create2EmptyBytecode(); } assembly ("memory-safe") { addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) // if no address was created, and returndata is not empty, bubble revert if and(iszero(addr), not(iszero(returndatasize()))) { let p := mload(0x40) returndatacopy(p, 0, returndatasize()) revert(p, returndatasize()) } } if (addr == address(0)) { revert Errors.FailedDeployment(); } } /** * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the * `bytecodeHash` or `salt` will result in a new destination address. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) { return computeAddress(salt, bytecodeHash, address(this)); } /** * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) { assembly ("memory-safe") { let ptr := mload(0x40) // Get free memory pointer // | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... | // |-------------------|---------------------------------------------------------------------------| // | bytecodeHash | CCCCCCCCCCCCC...CC | // | salt | BBBBBBBBBBBBB...BB | // | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA | // | 0xFF | FF | // |-------------------|---------------------------------------------------------------------------| // | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC | // | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ | mstore(add(ptr, 0x40), bytecodeHash) mstore(add(ptr, 0x20), salt) mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff mstore8(start, 0xff) addr := and(keccak256(start, 85), 0xffffffffffffffffffffffffffffffffffffffff) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { bool private _paused; /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); /** * @dev The operation failed because the contract is paused. */ error EnforcedPause(); /** * @dev The operation failed because the contract is not paused. */ error ExpectedPause(); /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { if (paused()) { revert EnforcedPause(); } } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) { revert ExpectedPause(); } } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
pragma solidity >=0.5.0; interface IUniswapV2Factory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; }
pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
pragma solidity >=0.6.2; import "./IUniswapV2Router01.sol"; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/governance/IGovernor.sol"; interface ITheFactory { function proposeAgent( string memory name, string memory symbol, string memory tokenURI, uint8[] memory cores // , // bytes32 tbaSalt, // address tbaImplementation, // uint32 daoVotingPeriod, // uint256 daoThreshold ) external returns (uint256); function withdraw(uint256 id) external; function totalAgents() external view returns (uint256); // function initFromToken( // address tokenAddr, // uint8[] memory cores, // bytes32 tbaSalt, // address tbaImplementation, // uint32 daoVotingPeriod, // uint256 daoThreshold, // uint256 initialLP // ) external returns (uint256); // function executeTokenApplication( // uint256 id, // bool canStake // ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IERC20Config.sol"; import "./IErrors.sol"; interface IAgentToken is IERC20, IERC20Config, IERC20Metadata, IErrors { event AutoSwapThresholdUpdated(uint256 oldThreshold, uint256 newThreshold); event ExternalCallError(uint256 identifier); event InitialLiquidityAdded( uint256 tokenA, uint256 tokenB, uint256 lpToken ); event LimitsUpdated( uint256 oldMaxTokensPerTransaction, uint256 newMaxTokensPerTransaction, uint256 oldMaxTokensPerWallet, uint256 newMaxTokensPerWallet ); event LiquidityPoolCreated(address addedPool); event LiquidityPoolAdded(address addedPool); event LiquidityPoolRemoved(address removedPool); event ProjectTaxBasisPointsChanged( uint256 oldBuyBasisPoints, uint256 newBuyBasisPoints, uint256 oldSellBasisPoints, uint256 newSellBasisPoints ); event RevenueAutoSwap(); event ProjectTaxRecipientUpdated(address treasury); event ValidCallerAdded(bytes32 addedValidCaller); event ValidCallerRemoved(bytes32 removedValidCaller); /** * @dev function {addInitialLiquidity} * * Add initial liquidity to the uniswap pair * * @param lpOwner The recipient of LP tokens */ function addInitialLiquidity(address lpOwner) external; /** * @dev function {isLiquidityPool} * * Return if an address is a liquidity pool * * @param queryAddress_ The address being queried * @return bool The address is / isn't a liquidity pool */ function isLiquidityPool( address queryAddress_ ) external view returns (bool); /** * @dev function {liquidityPools} * * Returns a list of all liquidity pools * * @return liquidityPools_ a list of all liquidity pools */ function liquidityPools() external view returns (address[] memory liquidityPools_); /** * @dev function {addLiquidityPool} onlyOwner * * Allows the manager to add a liquidity pool to the pool enumerable set * * @param newLiquidityPool_ The address of the new liquidity pool */ function addLiquidityPool(address newLiquidityPool_) external; /** * @dev function {removeLiquidityPool} onlyOwner * * Allows the manager to remove a liquidity pool * * @param removedLiquidityPool_ The address of the old removed liquidity pool */ function removeLiquidityPool(address removedLiquidityPool_) external; /** * @dev function {isValidCaller} * * Return if an address is a valid caller * * @param queryHash_ The code hash being queried * @return bool The address is / isn't a valid caller */ function isValidCaller(bytes32 queryHash_) external view returns (bool); /** * @dev function {validCallers} * * Returns a list of all valid caller code hashes * * @return validCallerHashes_ a list of all valid caller code hashes */ function validCallers() external view returns (bytes32[] memory validCallerHashes_); /** * @dev function {addValidCaller} onlyOwner * * Allows the owner to add the hash of a valid caller * * @param newValidCallerHash_ The hash of the new valid caller */ function addValidCaller(bytes32 newValidCallerHash_) external; /** * @dev function {removeValidCaller} onlyOwner * * Allows the owner to remove a valid caller * * @param removedValidCallerHash_ The hash of the old removed valid caller */ function removeValidCaller(bytes32 removedValidCallerHash_) external; /** * @dev function {setProjectTaxRecipient} onlyOwner * * Allows the manager to set the project tax recipient address * * @param projectTaxRecipient_ New recipient address */ function setProjectTaxRecipient(address projectTaxRecipient_) external; /** * @dev function {setSwapThresholdBasisPoints} onlyOwner * * Allows the manager to set the autoswap threshold * * @param swapThresholdBasisPoints_ New swap threshold in basis points */ function setSwapThresholdBasisPoints( uint16 swapThresholdBasisPoints_ ) external; /** * @dev function {setProjectTaxRates} onlyOwner * * Change the tax rates, subject to only ever decreasing * * @param newProjectBuyTaxBasisPoints_ The new buy tax rate * @param newProjectSellTaxBasisPoints_ The new sell tax rate */ function setProjectTaxRates( uint16 newProjectBuyTaxBasisPoints_, uint16 newProjectSellTaxBasisPoints_ ) external; /** * @dev totalBuyTaxBasisPoints * * Provide easy to view tax total: */ function totalBuyTaxBasisPoints() external view returns (uint256); /** * @dev totalSellTaxBasisPoints * * Provide easy to view tax total: */ function totalSellTaxBasisPoints() external view returns (uint256); /** * @dev distributeTaxTokens * * Allows the distribution of tax tokens to the designated recipient(s) * * As part of standard processing the tax token balance being above the threshold * will trigger an autoswap to ETH and distribution of this ETH to the designated * recipients. This is automatic and there is no need for user involvement. * * As part of this swap there are a number of calculations performed, particularly * if the tax balance is above MAX_SWAP_THRESHOLD_MULTIPLE. * * Testing indicates that these calculations are safe. But given the data / code * interactions it remains possible that some edge case set of scenarios may cause * an issue with these calculations. * * This method is therefore provided as a 'fallback' option to safely distribute * accumulated taxes from the contract, with a direct transfer of the ERC20 tokens * themselves. */ function distributeTaxTokens() external; /** * @dev function {withdrawETH} onlyOwner * * A withdraw function to allow ETH to be withdrawn by the manager * * This contract should never hold ETH. The only envisaged scenario where * it might hold ETH is a failed autoswap where the uniswap swap has completed, * the recipient of ETH reverts, the contract then wraps to WETH and the * wrap to WETH fails. * * This feels unlikely. But, for safety, we include this method. * * @param amount_ The amount to withdraw */ function withdrawETH(uint256 amount_) external; /** * @dev function {withdrawERC20} onlyOwner * * A withdraw function to allow ERC20s (except address(this)) to be withdrawn. * * This contract should never hold ERC20s other than tax tokens. The only envisaged * scenario where it might hold an ERC20 is a failed autoswap where the uniswap swap * has completed, the recipient of ETH reverts, the contract then wraps to WETH, the * wrap to WETH succeeds, BUT then the transfer of WETH fails. * * This feels even less likely than the scenario where ETH is held on the contract. * But, for safety, we include this method. * * @param token_ The ERC20 contract * @param amount_ The amount to withdraw */ function withdrawERC20(address token_, uint256 amount_) external; /** * @dev Destroys a `value` amount of tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 value) external; /** * @dev Destroys a `value` amount of tokens from `account`, deducting from * the caller's allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `value`. */ function burnFrom(address account, uint256 value) external; /** * @dev {initializer} * * @param integrationAddresses_ The project owner, uniswap router, LP currency * @param baseParams_ configuration of this ERC20. * param supplyParams_ Supply configuration of this ERC20. * param taxParams_ Tax configuration of this ERC20 * param taxParams_ Launch pool configuration of this ERC20 * param lpSupply_ Initial supply to be minted for LP */ function initialize( address[3] memory integrationAddresses_, bytes memory baseParams_, bytes memory supplyParams_, bytes memory taxParams_ ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IERC20Config { struct ERC20Config { bytes baseParameters; bytes supplyParameters; bytes taxParameters; bytes poolParameters; } struct ERC20BaseParameters { string name; string symbol; } struct ERC20SupplyParameters { uint256 maxSupply; uint256 lpSupply; uint256 vaultSupply; uint256 maxTokensPerWallet; uint256 maxTokensPerTxn; uint256 botProtectionDurationInSeconds; address vault; } struct ERC20TaxParameters { uint256 projectBuyTaxBasisPoints; uint256 projectSellTaxBasisPoints; uint256 taxSwapThresholdBasisPoints; address projectTaxRecipient; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IErrors { enum BondingCurveErrorType { OK, // No error INVALID_NUMITEMS, // The numItem value is 0 SPOT_PRICE_OVERFLOW // The updated spot price doesn't fit into 128 bits } error AdapterParamsMustBeEmpty(); // The adapter parameters on this LZ call must be empty. error AdditionToPoolIsBelowPerTransactionMinimum(); // The contribution amount is less than the minimum. error AdditionToPoolWouldExceedPoolCap(); // This addition to the pool would exceed the pool cap. error AdditionToPoolWouldExceedPerAddressCap(); // This addition to the pool would exceed the per address cap. error AddressAlreadySet(); // The address being set can only be set once, and is already non-0. error AllowanceDecreasedBelowZero(); // You cannot decrease the allowance below zero. error AlreadyInitialised(); // The contract is already initialised: it cannot be initialised twice! error ApprovalCallerNotOwnerNorApproved(); // The caller must own the token or be an approved operator. error ApproveFromTheZeroAddress(); // Approval cannot be called from the zero address (indeed, how have you??). error ApproveToTheZeroAddress(); // Approval cannot be given to the zero address. error ApprovalQueryForNonexistentToken(); // The token does not exist. error AuctionStatusIsNotEnded(); // Throw if the action required the auction to be closed, and it isn't. error AuctionStatusIsNotOpen(); // Throw if the action requires the auction to be open, and it isn't. error AuxCallFailed( address[] modules, uint256 value, bytes data, uint256 txGas ); // An auxilliary call from the drop factory failed. error BalanceMismatch(); // An error when comparing balance amounts. error BalanceQueryForZeroAddress(); // Cannot query the balance for the zero address. error BidMustBeBelowTheFloorWhenReducingQuantity(); // Only bids that are below the floor can reduce the quantity of the bid. error BidMustBeBelowTheFloorForRefundDuringAuction(); // Only bids that are below the floor can be refunded during the auction. error BondingCurveError(BondingCurveErrorType error); // An error of the type specified has occured in bonding curve processing. error BurnExceedsBalance(); // The amount you have selected to burn exceeds the addresses balance. error BurnFromTheZeroAddress(); // Tokens cannot be burned from the zero address. (Also, how have you called this!?!) error CallerIsNotDepositBoxOwner(); // The caller is not the owner of the deposit box. error CallerIsNotFactory(); // The caller of this function must match the factory address in storage. error CallerIsNotFactoryOrProjectOwner(); // The caller of this function must match the factory address OR project owner address. error CallerIsNotFactoryProjectOwnerOrPool(); // The caller of this function must match the factory address, project owner or pool address. error CallerIsNotTheOwner(); // The caller is not the owner of this contract. error CallerIsNotTheManager(); // The caller is not the manager of this contract. error CallerMustBeLzApp(); // The caller must be an LZ application. error CallerIsNotPlatformAdmin(address caller); // The caller of this function must be part of the platformAdmin group. error CallerIsNotSuperAdmin(address caller); // The caller of this function must match the superAdmin address in storage. error CannotAddLiquidityOnCreateAndUseDRIPool(); // Cannot use both liquidity added on create and a DRIPool in the same token. error CannotSetNewOwnerToTheZeroAddress(); // You can't set the owner of this contract to the zero address (address(0)). error CannotSetToZeroAddress(); // The corresponding address cannot be set to the zero address (address(0)). error CannotSetNewManagerToTheZeroAddress(); // Cannot transfer the manager to the zero address (address(0)). error CannotWithdrawThisToken(); // Cannot withdraw the specified token. error CanOnlyReduce(); // The given operation can only reduce the value specified. error CollectionAlreadyRevealed(); // The collection is already revealed; you cannot call reveal again. error ContractIsDecommissioned(); // This contract is decommissioned! error ContractIsPaused(); // The call requires the contract to be unpaused, and it is paused. error ContractIsNotPaused(); // The call required the contract to be paused, and it is NOT paused. error DecreasedAllowanceBelowZero(); // The request would decrease the allowance below zero, and that is not allowed. error DestinationIsNotTrustedSource(); // The destination that is being called through LZ has not been set as trusted. error DeployerOnly(); // This method can only be called by the deployer address. error DeploymentError(); // Error on deployment. error DepositBoxIsNotOpen(); // This action cannot complete as the deposit box is not open. error DriPoolAddressCannotBeAddressZero(); // The Dri Pool address cannot be the zero address. error GasLimitIsTooLow(); // The gas limit for the LayerZero call is too low. error IncorrectConfirmationValue(); // You need to enter the right confirmation value to call this funtion (usually 69420). error IncorrectPayment(); // The function call did not include passing the correct payment. error InitialLiquidityAlreadyAdded(); // Initial liquidity has already been added. You can't do it again. error InitialLiquidityNotYetAdded(); // Initial liquidity needs to have been added for this to succedd. error InsufficientAllowance(); // There is not a high enough allowance for this operation. error InvalidAdapterParams(); // The current adapter params for LayerZero on this contract won't work :(. error InvalidAddress(); // An address being processed in the function is not valid. error InvalidEndpointCaller(); // The calling address is not a valid LZ endpoint. The LZ endpoint was set at contract creation // and cannot be altered after. Check the address LZ endpoint address on the contract. error InvalidMinGas(); // The minimum gas setting for LZ in invalid. error InvalidOracleSignature(); // The signature provided with the contract call is not valid, either in format or signer. error InvalidPayload(); // The LZ payload is invalid error InvalidReceiver(); // The address used as a target for funds is not valid. error InvalidSourceSendingContract(); // The LZ message is being related from a source contract on another chain that is NOT trusted. error InvalidTotalShares(); // Total shares must equal 100 percent in basis points. error LimitsCanOnlyBeRaised(); // Limits are UP ONLY. error ListLengthMismatch(); // Two or more lists were compared and they did not match length. error LiquidityPoolMustBeAContractAddress(); // Cannot add a non-contract as a liquidity pool. error LiquidityPoolCannotBeAddressZero(); // Cannot add a liquidity pool from the zero address. error LPLockUpMustFitUint88(); // LP lockup is held in a uint88, so must fit. error NoTrustedPathRecord(); // LZ needs a trusted path record for this to work. What's that, you ask? error MachineAddressCannotBeAddressZero(); // Cannot set the machine address to the zero address. error ManagerUnauthorizedAccount(); // The caller is not the pending manager. error MaxBidQuantityIs255(); // Validation: as we use a uint8 array to track bid positions the max bid quantity is 255. error MaxPublicMintAllowanceExceeded( uint256 requested, uint256 alreadyMinted, uint256 maxAllowance ); // The calling address has requested a quantity that would exceed the max allowance. error MaxSupplyTooHigh(); // Max supply must fit in a uint128. error MaxTokensPerWalletExceeded(); // The transfer would exceed the max tokens per wallet limit. error MaxTokensPerTxnExceeded(); // The transfer would exceed the max tokens per transaction limit. error MetadataIsLocked(); // The metadata on this contract is locked; it cannot be altered! error MinGasLimitNotSet(); // The minimum gas limit for LayerZero has not been set. error MintERC2309QuantityExceedsLimit(); // The `quantity` minted with ERC2309 exceeds the safety limit. error MintingIsClosedForever(); // Minting is, as the error suggests, so over (and locked forever). error MintToZeroAddress(); // Cannot mint to the zero address. error MintZeroQuantity(); // The quantity of tokens minted must be more than zero. error NewBuyTaxBasisPointsExceedsMaximum(); // Project owner trying to set the tax rate too high. error NewSellTaxBasisPointsExceedsMaximum(); // Project owner trying to set the tax rate too high. error NoETHForLiquidityPair(); // No ETH has been provided for the liquidity pair. error TaxPeriodStillInForce(); // The minimum tax period has not yet expired. error NoPaymentDue(); // No payment is due for this address. error NoRefundForCaller(); // Error thrown when the calling address has no refund owed. error NoStoredMessage(); // There is no stored message matching the passed parameters. error NothingToClaim(); // The calling address has nothing to claim. error NoTokenForLiquidityPair(); // There is no token to add to the LP. error OperationDidNotSucceed(); // The operation failed (vague much?). error OracleSignatureHasExpired(); // A signature has been provided but it is too old. error OwnershipNotInitializedForExtraData(); // The `extraData` cannot be set on an uninitialized ownership slot. error OwnerQueryForNonexistentToken(); // The token does not exist. error CallerIsNotAdminNorFactory(); // The caller of this function must match the factory address or be an admin. error ParametersDoNotMatchSignedMessage(); // The parameters passed with the signed message do not match the message itself. error ParamTooLargeStartDate(); // The passed parameter exceeds the var type max. error ParamTooLargeEndDate(); // The passed parameter exceeds the var type max. error ParamTooLargeMinETH(); // The passed parameter exceeds the var type max. error ParamTooLargePerAddressMax(); // The passed parameter exceeds the var type max. error ParamTooLargeVestingDays(); // The passed parameter exceeds the var type max. error ParamTooLargePoolSupply(); // The passed parameter exceeds the var type max. error ParamTooLargePoolPerTxnMinETH(); // The passed parameter exceeds the var type max. error PassedConfigDoesNotMatchApproved(); // The config provided on the call does not match the approved config. error PauseCutOffHasPassed(); // The time period in which we can pause has passed; this contract can no longer be paused. error PaymentMustCoverPerMintFee(); // The payment passed must at least cover the per mint fee for the quantity requested. error PermitDidNotSucceed(); // The safeERC20 permit failed. error PlatformAdminCannotBeAddressZero(); // We cannot use the zero address (address(0)) as a platformAdmin. error PlatformTreasuryCannotBeAddressZero(); // The treasury address cannot be set to the zero address. error PoolIsAboveMinimum(); // You required the pool to be below the minimum, and it is not error PoolIsBelowMinimum(); // You required the pool to be above the minimum, and it is not error PoolPhaseIsClosed(); // The block.timestamp is either before the pool is open or after it is closed. error PoolPhaseIsNotAfter(); // The block.timestamp is either before or during the pool open phase. error PoolVestingNotYetComplete(); // Tokens in the pool are not yet vested. error ProjectOwnerCannotBeAddressZero(); // The project owner has to be a non zero address. error ProofInvalid(); // The provided proof is not valid with the provided arguments. error QuantityExceedsRemainingCollectionSupply(); // The requested quantity would breach the collection supply. error QuantityExceedsRemainingPhaseSupply(); // The requested quantity would breach the phase supply. error QuantityExceedsMaxPossibleCollectionSupply(); // The requested quantity would breach the maximum trackable supply error ReferralIdAlreadyUsed(); // This referral ID has already been used; they are one use only. error RequestingMoreThanAvailableBalance(); // The request exceeds the available balance. error RequestingMoreThanRemainingAllocation( uint256 previouslyMinted, uint256 requested, uint256 remainingAllocation ); // Number of tokens requested for this mint exceeds the remaining allocation (taking the // original allocation from the list and deducting minted tokens). error RoyaltyFeeWillExceedSalePrice(); // The ERC2981 royalty specified will exceed the sale price. error ShareTotalCannotBeZero(); // The total of all the shares cannot be nothing. error SliceOutOfBounds(); // The bytes slice operation was out of bounds. error SliceOverflow(); // The bytes slice operation overlowed. error SuperAdminCannotBeAddressZero(); // The superAdmin cannot be the sero address (address(0)). error SupplyTotalMismatch(); // The sum of the team supply and lp supply does not match. error SupportWindowIsNotOpen(); // The project owner has not requested support within the support request expiry window. error TaxFreeAddressCannotBeAddressZero(); // A tax free address cannot be address(0) error TemplateCannotBeAddressZero(); // The address for a template cannot be address zero (address(0)). error TemplateNotFound(); // There is no template that matches the passed template Id. error ThisMintIsClosed(); // It's over (well, this mint is, anyway). error TotalSharesMustMatchDenominator(); // The total of all shares must equal the denominator value. error TransferAmountExceedsBalance(); // The transfer amount exceeds the accounts available balance. error TransferCallerNotOwnerNorApproved(); // The caller must own the token or be an approved operator. error TransferFailed(); // The transfer has failed. error TransferFromIncorrectOwner(); // The token must be owned by `from`. error TransferToNonERC721ReceiverImplementer(); // Cannot safely transfer to a contract that does not implement the ERC721Receiver interface. error TransferFromZeroAddress(); // Cannot transfer from the zero address. Indeed, this surely is impossible, and likely a waste to check?? error TransferToZeroAddress(); // Cannot transfer to the zero address. error UnrecognisedVRFMode(); // Currently supported VRF modes are 0: chainlink and 1: arrng error URIQueryForNonexistentToken(); // The token does not exist. error ValueExceedsMaximum(); // The value sent exceeds the maximum allowed (super useful explanation huh?). error VRFCoordinatorCannotBeAddressZero(); // The VRF coordinator cannot be the zero address (address(0)). }
{ "optimizer": { "enabled": true, "runs": 200 }, "viaIR": true, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"FailedDeployment","type":"error"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newThreshold","type":"uint256"}],"name":"ApplicationThresholdUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"NewApplication","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"virtualId","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"lp","type":"address"}],"name":"NewPersona","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WITHDRAW_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allTradingTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"applicationThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"canStake","type":"bool"}],"name":"executeApplication","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"getApplication","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"tokenURI","type":"string"},{"internalType":"enum TheFactory.ApplicationStatus","name":"status","type":"uint8"},{"internalType":"uint256","name":"withdrawableAmount","type":"uint256"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint8[]","name":"cores","type":"uint8[]"}],"internalType":"struct TheFactory.Application","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenImplementation_","type":"address"},{"internalType":"uint256","name":"nextId_","type":"uint256"},{"internalType":"address","name":"assetToken_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maturityDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"tokenURI","type":"string"},{"internalType":"uint8[]","name":"cores","type":"uint8[]"}],"name":"proposeAgent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newThreshold","type":"uint256"}],"name":"setApplicationThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newToken","type":"address"}],"name":"setAssetToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"setImplementations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"setMaturityDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTokenAdmin","type":"address"}],"name":"setTokenAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"lpSupply","type":"uint256"},{"internalType":"uint256","name":"vaultSupply","type":"uint256"},{"internalType":"uint256","name":"maxTokensPerWallet","type":"uint256"},{"internalType":"uint256","name":"maxTokensPerTxn","type":"uint256"},{"internalType":"uint256","name":"botProtectionDurationInSeconds","type":"uint256"},{"internalType":"address","name":"vault","type":"address"}],"name":"setTokenSupplyParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"projectBuyTaxBasisPoints","type":"uint256"},{"internalType":"uint256","name":"projectSellTaxBasisPoints","type":"uint256"},{"internalType":"uint256","name":"taxSwapThresholdBasisPoints","type":"uint256"},{"internalType":"address","name":"projectTaxRecipient","type":"address"}],"name":"setTokenTaxParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"router","type":"address"}],"name":"setUniswapRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAgents","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60808060405234601f5760ff196001541660015561292590816100258239f35b600080fdfe608080604052600436101561001357600080fd5b600090813560e01c90816301ffc9a71461223857508063063513b71461221a5780631083f761146121f15780631f2f4bfd14611a7c578063248a9ca314611a4657806326bde5aa14611a065780632a7d4a1f146118665780632e1a7d4d1461175d5780632f2ff15d1461171c5780632f3a3d5d146116f357806336568abe146116ae5780633f4ba83a146116465780635c975abb146116235780635ca3cedf1461147d578063634282af14611403578063820e34d214610c6f5780638456cb5914610c1557806391d1485414610bcd5780639352dace14610b8d578063a217fddf14610b71578063aa3d000a14610501578063bd1cf258146104b3578063bea9849e14610473578063c350a1b5146102e0578063c5053712146102c2578063d547741f14610278578063d739ac2914610255578063ddf4427514610237578063e02023a1146101fc578063e887b1cc146101b85763f74575941461017657600080fd5b346101b55760203660031901126101b55761018f6122ce565b6101976125c3565b60018060a01b03166001600160601b0360a01b600c541617600c5580f35b80fd5b50346101b55760203660031901126101b55760043590600a548210156101b55760206101e3836122ff565b905460405160039290921b1c6001600160a01b03168152f35b50346101b557806003193601126101b55760206040517f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec8152f35b50346101b557806003193601126101b5576020600454604051908152f35b50346101b55760203660031901126101b55761026f6125c3565b60043560075580f35b50346101b55760403660031901126101b5576102be6004356102986122e9565b906102b96102b482600052600060205260016040600020015490565b612616565b6127c9565b5080f35b50346101b557806003193601126101b5576020600554604051908152f35b50346101b55760603660031901126101b5576102fa6122ce565b6044356001600160a01b0381169081900361046f576000805160206128d0833981519152549160ff8360401c1615926001600160401b03811680159081610467575b600114908161045d575b159081610454575b506104455767ffffffffffffffff1981166001176000805160206128d08339815191525583610418575b5060018060a01b03166001600160601b0360a01b60035416176003556001600160601b0360a01b60065416176006556024356002556103b63361268c565b506103be5780f35b68ff0000000000000000196000805160206128d083398151915254166000805160206128d0833981519152557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a180f35b68ffffffffffffffffff191668010000000000000001176000805160206128d08339815191525538610378565b63f92ee8a960e01b8552600485fd5b9050153861034e565b303b159150610346565b85915061033c565b8280fd5b50346101b55760203660031901126101b55761048d6122ce565b6104956125c3565b60018060a01b03166001600160601b0360a01b600b541617600b5580f35b50346101b55760203660031901126101b5577fcfa33021ab0175831433b2f3bd8eeb24a22f5ae53ca0e660a246811754f9e34a60206004356104f36125c3565b80600455604051908152a180f35b50346101b55760403660031901126101b55760043590602435801515036101b557600160095461053460ff8216156124ff565b60ff191617600955818152600860205260408120600501546001600160a01b031633148015610b32575b6105679061253c565b604051918183600d549161057a836123ef565b8083529260018116908115610b135750600114610ab5575b61059e92500384612361565b808252600860205260ff6003604084200154166003811015610aa1576105c49015612577565b600c546001600160a01b031615610a665781526008602052604081206004810192828454945560038201600160ff19825416179055600161062e60405193610617856106108184612429565b0386612361565b6106276040518094819301612429565b0382612361565b600354608881901c62ffffff16763d602d80600a3d3981f3363d3d373d3d3d363d7300000017855260781b6effffffffffffffffffffffffffffff19166e5af43d82803e903d91602b57fd5bf3176020526037600985f06001600160a01b038116939092908415610a575760405192606084018481106001600160401b03821117610a435791610718610726926107069460405260018060a01b03600c5416875260018060a01b03600b5416602088015260018060a01b0360065416604088015260405194859360406020860152606085019061228d565b838103601f190160408501529061228d565b03601f198101835282612361565b843b1561096a57604051634258efa960e11b81529286928492909184600485015b60038210610a1d575050509061076b61077d9260c0606486015260c485019061228d565b8381036003190160848501529061228d565b8181036003190160a4830152600e548391610797826123ef565b91828252846001821691826000146109ff5750506001146109a1575b50508190038183875af1801561096e5761098d575b50600a54600160401b811015610979578060016107e89201600a556122ff565b81546001600160a01b0360039290921b91821b19169084901b17905560405163d6efd7c360e01b81528381600481865afa90811561096e5784916108bd575b5051156108a9576006549293849361084892906001600160a01b0316612651565b803b156108a657818091602460405180948193631672aef960e21b83523060048401525af1801561089b57610886575b5060ff196009541660095580f35b8161089091612361565b6101b5578038610878565b6040513d84823e3d90fd5b50fd5b634e487b7160e01b83526032600452602483fd5b90503d8085833e6108ce8183612361565b810190602081830312610966578051906001600160401b03821161096a57019080601f8301121561096657815190610905826123d8565b926109136040519485612361565b82845260208085019360051b82010191821161096257602001915b81831061093e5750505038610827565b82516001600160a01b038116810361095e5781526020928301920161092e565b8780fd5b8680fd5b8480fd5b8580fd5b6040513d86823e3d90fd5b634e487b7160e01b84526041600452602484fd5b8361099a91949294612361565b91386107c8565b600e8552849250907fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd5b8184106109df5750500160200181386107b3565b6001919550602092945080548385870101520191019091879385936109cb565b909450602093915060ff191683830152151560051b010190386107b3565b82516001600160a01b031681528a96508795506020928301926001929092019101610747565b634e487b7160e01b88526041600452602488fd5b63b06ebf3d60e01b8652600486fd5b60405162461bcd60e51b8152602060048201526013602482015272151bdad95b8818591b5a5b881b9bdd081cd95d606a1b6044820152606490fd5b634e487b7160e01b83526021600452602483fd5b50600d84529083907fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb55b818310610af757505090602061059e92820101610592565b6020919350806001915483858a01015201910190918592610adf565b6020925061059e94915060ff191682840152151560051b820101610592565b507f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec81526020818152604080832033845290915281205460ff1661055e565b50346101b557806003193601126101b557602090604051908152f35b50346101b55760203660031901126101b557610ba76122ce565b610baf6125c3565b60018060a01b03166001600160601b0360a01b600354161760035580f35b50346101b55760403660031901126101b55760ff6040602092610bee6122e9565b60043582528185528282206001600160a01b03909116825284522054604051911615158152f35b50346101b557806003193601126101b557610c2e6125c3565b610c3661284b565b600160ff19815416176001557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a180f35b50346101b55760803660031901126101b5576004356001600160401b0381116113ff57610ca0903690600401612382565b6024356001600160401b03811161046f57610cbf903690600401612382565b6044356001600160401b0381116113d957610cde903690600401612382565b92606435926001600160401b0384116113ff57366023850112156113ff578360040135610d0a816123d8565b94610d186040519687612361565b8186526024602087019260051b8201019036821161096657602401915b8183106113e557505050610d4761284b565b6006546040516370a0823160e01b81523360048201526001600160a01b0390911690602081602481855afa90811561096e5784916113af575b5060045480911061136a57604051636eb1769f60e11b8152336004820152306024820152602081604481865afa90811561135f57908291869161132a575b50106112da5785511561129c57610e0591604051916323b872dd60e01b6020840152336024840152306044840152606483015260648252610e00608483612361565b612868565b600254926000198414611288576001840160025560045460405192610e2984612330565b8352602083019182526040830196875260608301968488526080840191825260a084019233845260c0850197885286865260086020526040862094518051906001600160401b038211610a4357610e8a82610e8489546123ef565b896124c3565b602090601f831160011461122557610eba9291899183611140575b50508160011b916000199060031b1c19161790565b85555b51805160018601916001600160401b038211610a4357610ee782610ee185546123ef565b856124c3565b602090601f83116001146111c257610f1692918991836111405750508160011b916000199060031b1c19161790565b90555b51805160028501916001600160401b0382116111ae57610f3d82610ee185546123ef565b602090601f831160011461114b57610f6c92918891836111405750508160011b916000199060031b1c19161790565b90555b60038301965196600388101561112c57849596976006955060ff80198354169116179055516004830155600582019060018060a01b039051166001600160601b0360a01b8254161790550192518051906001600160401b03821161111857600160401b82116111185760209085548387558084106110cc575b5001938252602082208160051c91835b83811061108d5750601f198116900380611041575b6020857f0ff47c4a3dc48719ecfd1876116e80d7d76ec7cb67248ae49449f9104747af2982604051838152a1604051908152f35b9483955b80871061105d5750506020945001553880808061100d565b909360206110826001928960ff895116919060ff809160031b9316831b921b19161790565b950196019590611045565b84855b602081106110a5575083820155600101610ff8565b885190989160019160209160ff60038d901b81811b199092169216901b1792019801611090565b6110f690878652838620601f80870160051c820192818816806110fc575b500160051c01906124ac565b38610fe8565b600019850190815490600019908a0360031b1c169055386110ea565b634e487b7160e01b83526041600452602483fd5b634e487b7160e01b85526021600452602485fd5b015190503880610ea5565b8388528188209190601f198416895b818110611196575090846001959493921061117d575b505050811b019055610f6f565b015160001960f88460031b161c19169055388080611170565b9293602060018192878601518155019501930161115a565b634e487b7160e01b87526041600452602487fd5b8389528189209190601f1984168a5b81811061120d57509084600195949392106111f4575b505050811b019055610f19565b015160001960f88460031b161c191690553880806111e7565b929360206001819287860151815501950193016111d1565b8789528189209190601f1984168a5b8181106112705750908460019594939210611257575b505050811b018555610ebd565b015160001960f88460031b161c1916905538808061124a565b92936020600181928786015181550195019301611234565b634e487b7160e01b83526011600452602483fd5b60405162461bcd60e51b815260206004820152601660248201527510dbdc995cc81b5d5cdd081899481c1c9bdd9a59195960521b6044820152606490fd5b60405162461bcd60e51b815260206004820152602260248201527f496e73756666696369656e7420617373657420746f6b656e20616c6c6f77616e604482015261636560f01b6064820152608490fd5b9150506020813d602011611357575b8161134660209383612361565b810103126109665781905138610dbe565b3d9150611339565b6040513d87823e3d90fd5b60405162461bcd60e51b815260206004820152601860248201527f496e73756666696369656e7420617373657420746f6b656e00000000000000006044820152606490fd5b90506020813d6020116113dd575b816113ca60209383612361565b810103126113d9575138610d80565b8380fd5b3d91506113bd565b823560ff8116810361096a57815260209283019201610d35565b5080fd5b50346101b55760203660031901126101b557600435906005548210156101b55760055482101561146957600590527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db001546040516001600160a01b039091168152602090f35b634e487b7160e01b81526032600452602490fd5b50346101b55760803660031901126101b5576064356001600160a01b03811691908290036101b5576114ad6125c3565b604051916004356020840152602435604084015260443560608401526080830152608082526114dd60a083612361565b81516001600160401b03811161160f576114f8600e546123ef565b601f81116115b6575b50602092601f8211600114611538578293829161153294926111405750508160011b916000199060031b1c19161790565b600e5580f35b600e8352601f198216937fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd91845b86811061159e5750836001959610611585575b505050811b01600e5580f35b015160001960f88460031b161c19169055388080611579565b91926020600181928685015181550194019201611566565b600e83526115ff907fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd601f840160051c81019160208510611605575b601f0160051c01906124ac565b38611501565b90915081906115f2565b634e487b7160e01b82526041600452602482fd5b50346101b557806003193601126101b557602060ff600154166040519015158152f35b50346101b557806003193601126101b55761165f6125c3565b60015460ff81161561169f5760ff19166001557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a180f35b638dfc202b60e01b8252600482fd5b50346101b55760403660031901126101b5576116c86122e9565b336001600160a01b038216036116e4576102be906004356127c9565b63334bd91960e11b8252600482fd5b50346101b557806003193601126101b5576003546040516001600160a01b039091168152602090f35b50346101b55760403660031901126101b5576102be60043561173c6122e9565b906117586102b482600052600060205260016040600020015490565b61273e565b50346101b55760203660031901126101b557600160095461178160ff8216156124ff565b60ff1916176009556004358152600860205260408120906005820160018060a01b0381541633148015611827575b6117b89061253c565b600383019060ff82541660038110156118135761180693946117dc60049215612577565b01805490859055825460ff191660021790925560065490546001600160a01b039081169116612651565b60ff196009541660095580f35b634e487b7160e01b84526021600452602484fd5b507f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec82526020828152604080842033855290915282205460ff166117af565b50346101b55760e03660031901126101b55760c4356001600160a01b03811691908290036101b5576118966125c3565b60405191600435602084015260243560408401526044356060840152606435608084015260843560a084015260a43560c084015260e083015260e082526118df61010083612361565b81516001600160401b03811161160f576118fa600d546123ef565b601f81116119b8575b50602092601f821160011461193a578293829161193494926111405750508160011b916000199060031b1c19161790565b600d5580f35b600d8352601f198216937fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb591845b8681106119a05750836001959610611987575b505050811b01600d5580f35b015160001960f88460031b161c1916905538808061197b565b91926020600181928685015181550194019201611968565b600d8352611a00907fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5601f840160051c8101916020851061160557601f0160051c01906124ac565b38611903565b50346101b55760203660031901126101b557611a206122ce565b611a286125c3565b60018060a01b03166001600160601b0360a01b600654161760065580f35b50346101b55760203660031901126101b5576020611a74600435600052600060205260016040600020015490565b604051908152f35b50346101b55760203660031901126101b557606060c0604051611a9e81612330565b82815282602082015282604082015283838201528360808201528360a0820152015260043581526008602052604081209060405191611adc83612330565b604051611aed816106278185612429565b8352604051611b03816106278160018601612429565b6020840190815260405191611b2683611b1f8160028501612429565b0384612361565b6040850192835260ff6003820154169260608601936003811015611d6257845260048201549060808701918252600660018060a01b036005850154169360a08901948552019360405180958691602082549182815201918a5260208a20908a915b81601f8401106120495792611ca992611ce19592611cf49897955491818110612035575b81811061201e575b818110612007575b818110611ff0575b818110611fda575b818110611fc3575b818110611fac575b818110611f95575b818110611f7e575b818110611f67575b818110611f50575b818110611f39575b818110611f22575b818110611f0b575b818110611ef4575b818110611edd575b818110611ec6575b818110611eaf575b818110611e98575b818110611e81575b818110611e6a575b818110611e53575b818110611e3c575b818110611e25575b818110611e0e575b818110611df7575b818110611de0575b818110611dc9575b818110611db2575b818110611d9b575b818110611d84575b10611d76575b500388612361565b60c08a01968752611cce6040519a60208c525160e060208d01526101008c019061228d565b90518a8203601f190160408c015261228d565b9051888203601f190160608a015261228d565b93516003811015611d625760808701525160a0860152516001600160a01b031660c085015251838203601f190160e085015280518083528493602093840193909201915b818110611d46575050500390f35b825160ff16845285945060209384019390920191600101611d38565b634e487b7160e01b86526021600452602486fd5b60f81c815260200138611ca1565b92602060019160ff8560f01c168152019301611c9b565b92602060019160ff8560e81c168152019301611c93565b92602060019160ff8560e01c168152019301611c8b565b92602060019160ff8560d81c168152019301611c83565b92602060019160ff8560d01c168152019301611c7b565b92602060019160ff8560c81c168152019301611c73565b92602060019160ff8560c01c168152019301611c6b565b92602060019160ff8560b81c168152019301611c63565b92602060019160ff8560b01c168152019301611c5b565b92602060019160ff8560a81c168152019301611c53565b92602060019160ff8560a01c168152019301611c4b565b92602060019160ff8560981c168152019301611c43565b92602060019160ff8560901c168152019301611c3b565b92602060019160ff8560881c168152019301611c33565b92602060019160ff8560801c168152019301611c2b565b92602060019160ff8560781c168152019301611c23565b92602060019160ff8560701c168152019301611c1b565b92602060019160ff8560681c168152019301611c13565b92602060019160ff8560601c168152019301611c0b565b92602060019160ff8560581c168152019301611c03565b92602060019160ff8560501c168152019301611bfb565b92602060019160ff8560481c168152019301611bf3565b92602060019160ff8560401c168152019301611beb565b92602060019160ff8560381c168152019301611be3565b92602060019160ff8560301c168152019301611bdb565b92602060019160ff8560281c168152019301611bd3565b92602060019160ff85831c168152019301611bcb565b92602060019160ff8560181c168152019301611bc3565b92602060019160ff8560101c168152019301611bbb565b92602060019160ff8560081c168152019301611bb3565b92602060019160ff85168152019301611bab565b935090916001610400602092865460ff8116825260ff8160081c168583015260ff8160101c16604083015260ff8160181c16606083015260ff81861c16608083015260ff8160281c1660a083015260ff8160301c1660c083015260ff8160381c1660e083015260ff8160401c1661010083015260ff8160481c1661012083015260ff8160501c1661014083015260ff8160581c1661016083015260ff8160601c1661018083015260ff8160681c166101a083015260ff8160701c166101c083015260ff8160781c166101e083015260ff8160801c1661020083015260ff8160881c1661022083015260ff8160901c1661024083015260ff8160981c1661026083015260ff8160a01c1661028083015260ff8160a81c166102a083015260ff8160b01c166102c083015260ff8160b81c166102e083015260ff8160c01c1661030083015260ff8160c81c1661032083015260ff8160d01c1661034083015260ff8160d81c1661036083015260ff8160e01c1661038083015260ff8160e81c166103a083015260ff8160f01c166103c083015260f81c6103e0820152019401920190889392611b87565b50346101b557806003193601126101b5576006546040516001600160a01b039091168152602090f35b50346101b557806003193601126101b5576020600754604051908152f35b9050346113ff5760203660031901126113ff5760043563ffffffff60e01b811680910361046f5760209250637965db0b60e01b811490811561227c575b5015158152f35b6301ffc9a760e01b14905038612275565b919082519283825260005b8481106122b9575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201612298565b600435906001600160a01b03821682036122e457565b600080fd5b602435906001600160a01b03821682036122e457565b600a5481101561231a57600a60005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b60e081019081106001600160401b0382111761234b57604052565b634e487b7160e01b600052604160045260246000fd5b90601f801991011681019081106001600160401b0382111761234b57604052565b81601f820112156122e4578035906001600160401b03821161234b57604051926123b6601f8401601f191660200185612361565b828452602083830101116122e457816000926020809301838601378301015290565b6001600160401b03811161234b5760051b60200190565b90600182811c9216801561241f575b602083101461240957565b634e487b7160e01b600052602260045260246000fd5b91607f16916123fe565b60009291815491612439836123ef565b808352926001811690811561248f575060011461245557505050565b60009081526020812093945091925b838310612475575060209250010190565b600181602092949394548385870101520191019190612464565b915050602093945060ff929192191683830152151560051b010190565b8181106124b7575050565b600081556001016124ac565b9190601f81116124d257505050565b6124fd926000526020600020906020601f840160051c8301931061160557601f0160051c01906124ac565b565b1561250657565b60405162461bcd60e51b815260206004820152600e60248201526d31b0b73737ba103932b2b73a32b960911b6044820152606490fd5b1561254357565b60405162461bcd60e51b815260206004820152600c60248201526b2737ba10383937b837b9b2b960a11b6044820152606490fd5b1561257e57565b60405162461bcd60e51b815260206004820152601960248201527f4170706c69636174696f6e206973206e6f7420616374697665000000000000006044820152606490fd5b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16156125fc57565b63e2517d3f60e01b60005233600452600060245260446000fd5b60008181526020818152604080832033845290915290205460ff16156126395750565b63e2517d3f60e01b6000523360045260245260446000fd5b60405163a9059cbb60e01b60208201526001600160a01b0390921660248301526044808301939093529181526124fd91610e00606483612361565b6001600160a01b03811660009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16612738576001600160a01b031660008181527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560205260408120805460ff191660011790553391907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a4600190565b50600090565b6000818152602081815260408083206001600160a01b038616845290915290205460ff166127c2576000818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b5050600090565b6000818152602081815260408083206001600160a01b038616845290915290205460ff16156127c2576000818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b60ff6001541661285757565b63d93c066560e01b60005260046000fd5b906000602091828151910182855af1156128c3576000513d6128ba57506001600160a01b0381163b155b6128995750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b60011415612892565b6040513d6000823e3d90fdfef0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a264697066735822122092d21f722413106e34835bf19607b553546784a20a8755d5d9dd69dcab773aa164736f6c634300081c0033
Deployed Bytecode
0x608080604052600436101561001357600080fd5b600090813560e01c90816301ffc9a71461223857508063063513b71461221a5780631083f761146121f15780631f2f4bfd14611a7c578063248a9ca314611a4657806326bde5aa14611a065780632a7d4a1f146118665780632e1a7d4d1461175d5780632f2ff15d1461171c5780632f3a3d5d146116f357806336568abe146116ae5780633f4ba83a146116465780635c975abb146116235780635ca3cedf1461147d578063634282af14611403578063820e34d214610c6f5780638456cb5914610c1557806391d1485414610bcd5780639352dace14610b8d578063a217fddf14610b71578063aa3d000a14610501578063bd1cf258146104b3578063bea9849e14610473578063c350a1b5146102e0578063c5053712146102c2578063d547741f14610278578063d739ac2914610255578063ddf4427514610237578063e02023a1146101fc578063e887b1cc146101b85763f74575941461017657600080fd5b346101b55760203660031901126101b55761018f6122ce565b6101976125c3565b60018060a01b03166001600160601b0360a01b600c541617600c5580f35b80fd5b50346101b55760203660031901126101b55760043590600a548210156101b55760206101e3836122ff565b905460405160039290921b1c6001600160a01b03168152f35b50346101b557806003193601126101b55760206040517f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec8152f35b50346101b557806003193601126101b5576020600454604051908152f35b50346101b55760203660031901126101b55761026f6125c3565b60043560075580f35b50346101b55760403660031901126101b5576102be6004356102986122e9565b906102b96102b482600052600060205260016040600020015490565b612616565b6127c9565b5080f35b50346101b557806003193601126101b5576020600554604051908152f35b50346101b55760603660031901126101b5576102fa6122ce565b6044356001600160a01b0381169081900361046f576000805160206128d0833981519152549160ff8360401c1615926001600160401b03811680159081610467575b600114908161045d575b159081610454575b506104455767ffffffffffffffff1981166001176000805160206128d08339815191525583610418575b5060018060a01b03166001600160601b0360a01b60035416176003556001600160601b0360a01b60065416176006556024356002556103b63361268c565b506103be5780f35b68ff0000000000000000196000805160206128d083398151915254166000805160206128d0833981519152557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a180f35b68ffffffffffffffffff191668010000000000000001176000805160206128d08339815191525538610378565b63f92ee8a960e01b8552600485fd5b9050153861034e565b303b159150610346565b85915061033c565b8280fd5b50346101b55760203660031901126101b55761048d6122ce565b6104956125c3565b60018060a01b03166001600160601b0360a01b600b541617600b5580f35b50346101b55760203660031901126101b5577fcfa33021ab0175831433b2f3bd8eeb24a22f5ae53ca0e660a246811754f9e34a60206004356104f36125c3565b80600455604051908152a180f35b50346101b55760403660031901126101b55760043590602435801515036101b557600160095461053460ff8216156124ff565b60ff191617600955818152600860205260408120600501546001600160a01b031633148015610b32575b6105679061253c565b604051918183600d549161057a836123ef565b8083529260018116908115610b135750600114610ab5575b61059e92500384612361565b808252600860205260ff6003604084200154166003811015610aa1576105c49015612577565b600c546001600160a01b031615610a665781526008602052604081206004810192828454945560038201600160ff19825416179055600161062e60405193610617856106108184612429565b0386612361565b6106276040518094819301612429565b0382612361565b600354608881901c62ffffff16763d602d80600a3d3981f3363d3d373d3d3d363d7300000017855260781b6effffffffffffffffffffffffffffff19166e5af43d82803e903d91602b57fd5bf3176020526037600985f06001600160a01b038116939092908415610a575760405192606084018481106001600160401b03821117610a435791610718610726926107069460405260018060a01b03600c5416875260018060a01b03600b5416602088015260018060a01b0360065416604088015260405194859360406020860152606085019061228d565b838103601f190160408501529061228d565b03601f198101835282612361565b843b1561096a57604051634258efa960e11b81529286928492909184600485015b60038210610a1d575050509061076b61077d9260c0606486015260c485019061228d565b8381036003190160848501529061228d565b8181036003190160a4830152600e548391610797826123ef565b91828252846001821691826000146109ff5750506001146109a1575b50508190038183875af1801561096e5761098d575b50600a54600160401b811015610979578060016107e89201600a556122ff565b81546001600160a01b0360039290921b91821b19169084901b17905560405163d6efd7c360e01b81528381600481865afa90811561096e5784916108bd575b5051156108a9576006549293849361084892906001600160a01b0316612651565b803b156108a657818091602460405180948193631672aef960e21b83523060048401525af1801561089b57610886575b5060ff196009541660095580f35b8161089091612361565b6101b5578038610878565b6040513d84823e3d90fd5b50fd5b634e487b7160e01b83526032600452602483fd5b90503d8085833e6108ce8183612361565b810190602081830312610966578051906001600160401b03821161096a57019080601f8301121561096657815190610905826123d8565b926109136040519485612361565b82845260208085019360051b82010191821161096257602001915b81831061093e5750505038610827565b82516001600160a01b038116810361095e5781526020928301920161092e565b8780fd5b8680fd5b8480fd5b8580fd5b6040513d86823e3d90fd5b634e487b7160e01b84526041600452602484fd5b8361099a91949294612361565b91386107c8565b600e8552849250907fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd5b8184106109df5750500160200181386107b3565b6001919550602092945080548385870101520191019091879385936109cb565b909450602093915060ff191683830152151560051b010190386107b3565b82516001600160a01b031681528a96508795506020928301926001929092019101610747565b634e487b7160e01b88526041600452602488fd5b63b06ebf3d60e01b8652600486fd5b60405162461bcd60e51b8152602060048201526013602482015272151bdad95b8818591b5a5b881b9bdd081cd95d606a1b6044820152606490fd5b634e487b7160e01b83526021600452602483fd5b50600d84529083907fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb55b818310610af757505090602061059e92820101610592565b6020919350806001915483858a01015201910190918592610adf565b6020925061059e94915060ff191682840152151560051b820101610592565b507f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec81526020818152604080832033845290915281205460ff1661055e565b50346101b557806003193601126101b557602090604051908152f35b50346101b55760203660031901126101b557610ba76122ce565b610baf6125c3565b60018060a01b03166001600160601b0360a01b600354161760035580f35b50346101b55760403660031901126101b55760ff6040602092610bee6122e9565b60043582528185528282206001600160a01b03909116825284522054604051911615158152f35b50346101b557806003193601126101b557610c2e6125c3565b610c3661284b565b600160ff19815416176001557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a180f35b50346101b55760803660031901126101b5576004356001600160401b0381116113ff57610ca0903690600401612382565b6024356001600160401b03811161046f57610cbf903690600401612382565b6044356001600160401b0381116113d957610cde903690600401612382565b92606435926001600160401b0384116113ff57366023850112156113ff578360040135610d0a816123d8565b94610d186040519687612361565b8186526024602087019260051b8201019036821161096657602401915b8183106113e557505050610d4761284b565b6006546040516370a0823160e01b81523360048201526001600160a01b0390911690602081602481855afa90811561096e5784916113af575b5060045480911061136a57604051636eb1769f60e11b8152336004820152306024820152602081604481865afa90811561135f57908291869161132a575b50106112da5785511561129c57610e0591604051916323b872dd60e01b6020840152336024840152306044840152606483015260648252610e00608483612361565b612868565b600254926000198414611288576001840160025560045460405192610e2984612330565b8352602083019182526040830196875260608301968488526080840191825260a084019233845260c0850197885286865260086020526040862094518051906001600160401b038211610a4357610e8a82610e8489546123ef565b896124c3565b602090601f831160011461122557610eba9291899183611140575b50508160011b916000199060031b1c19161790565b85555b51805160018601916001600160401b038211610a4357610ee782610ee185546123ef565b856124c3565b602090601f83116001146111c257610f1692918991836111405750508160011b916000199060031b1c19161790565b90555b51805160028501916001600160401b0382116111ae57610f3d82610ee185546123ef565b602090601f831160011461114b57610f6c92918891836111405750508160011b916000199060031b1c19161790565b90555b60038301965196600388101561112c57849596976006955060ff80198354169116179055516004830155600582019060018060a01b039051166001600160601b0360a01b8254161790550192518051906001600160401b03821161111857600160401b82116111185760209085548387558084106110cc575b5001938252602082208160051c91835b83811061108d5750601f198116900380611041575b6020857f0ff47c4a3dc48719ecfd1876116e80d7d76ec7cb67248ae49449f9104747af2982604051838152a1604051908152f35b9483955b80871061105d5750506020945001553880808061100d565b909360206110826001928960ff895116919060ff809160031b9316831b921b19161790565b950196019590611045565b84855b602081106110a5575083820155600101610ff8565b885190989160019160209160ff60038d901b81811b199092169216901b1792019801611090565b6110f690878652838620601f80870160051c820192818816806110fc575b500160051c01906124ac565b38610fe8565b600019850190815490600019908a0360031b1c169055386110ea565b634e487b7160e01b83526041600452602483fd5b634e487b7160e01b85526021600452602485fd5b015190503880610ea5565b8388528188209190601f198416895b818110611196575090846001959493921061117d575b505050811b019055610f6f565b015160001960f88460031b161c19169055388080611170565b9293602060018192878601518155019501930161115a565b634e487b7160e01b87526041600452602487fd5b8389528189209190601f1984168a5b81811061120d57509084600195949392106111f4575b505050811b019055610f19565b015160001960f88460031b161c191690553880806111e7565b929360206001819287860151815501950193016111d1565b8789528189209190601f1984168a5b8181106112705750908460019594939210611257575b505050811b018555610ebd565b015160001960f88460031b161c1916905538808061124a565b92936020600181928786015181550195019301611234565b634e487b7160e01b83526011600452602483fd5b60405162461bcd60e51b815260206004820152601660248201527510dbdc995cc81b5d5cdd081899481c1c9bdd9a59195960521b6044820152606490fd5b60405162461bcd60e51b815260206004820152602260248201527f496e73756666696369656e7420617373657420746f6b656e20616c6c6f77616e604482015261636560f01b6064820152608490fd5b9150506020813d602011611357575b8161134660209383612361565b810103126109665781905138610dbe565b3d9150611339565b6040513d87823e3d90fd5b60405162461bcd60e51b815260206004820152601860248201527f496e73756666696369656e7420617373657420746f6b656e00000000000000006044820152606490fd5b90506020813d6020116113dd575b816113ca60209383612361565b810103126113d9575138610d80565b8380fd5b3d91506113bd565b823560ff8116810361096a57815260209283019201610d35565b5080fd5b50346101b55760203660031901126101b557600435906005548210156101b55760055482101561146957600590527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db001546040516001600160a01b039091168152602090f35b634e487b7160e01b81526032600452602490fd5b50346101b55760803660031901126101b5576064356001600160a01b03811691908290036101b5576114ad6125c3565b604051916004356020840152602435604084015260443560608401526080830152608082526114dd60a083612361565b81516001600160401b03811161160f576114f8600e546123ef565b601f81116115b6575b50602092601f8211600114611538578293829161153294926111405750508160011b916000199060031b1c19161790565b600e5580f35b600e8352601f198216937fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd91845b86811061159e5750836001959610611585575b505050811b01600e5580f35b015160001960f88460031b161c19169055388080611579565b91926020600181928685015181550194019201611566565b600e83526115ff907fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd601f840160051c81019160208510611605575b601f0160051c01906124ac565b38611501565b90915081906115f2565b634e487b7160e01b82526041600452602482fd5b50346101b557806003193601126101b557602060ff600154166040519015158152f35b50346101b557806003193601126101b55761165f6125c3565b60015460ff81161561169f5760ff19166001557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a180f35b638dfc202b60e01b8252600482fd5b50346101b55760403660031901126101b5576116c86122e9565b336001600160a01b038216036116e4576102be906004356127c9565b63334bd91960e11b8252600482fd5b50346101b557806003193601126101b5576003546040516001600160a01b039091168152602090f35b50346101b55760403660031901126101b5576102be60043561173c6122e9565b906117586102b482600052600060205260016040600020015490565b61273e565b50346101b55760203660031901126101b557600160095461178160ff8216156124ff565b60ff1916176009556004358152600860205260408120906005820160018060a01b0381541633148015611827575b6117b89061253c565b600383019060ff82541660038110156118135761180693946117dc60049215612577565b01805490859055825460ff191660021790925560065490546001600160a01b039081169116612651565b60ff196009541660095580f35b634e487b7160e01b84526021600452602484fd5b507f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec82526020828152604080842033855290915282205460ff166117af565b50346101b55760e03660031901126101b55760c4356001600160a01b03811691908290036101b5576118966125c3565b60405191600435602084015260243560408401526044356060840152606435608084015260843560a084015260a43560c084015260e083015260e082526118df61010083612361565b81516001600160401b03811161160f576118fa600d546123ef565b601f81116119b8575b50602092601f821160011461193a578293829161193494926111405750508160011b916000199060031b1c19161790565b600d5580f35b600d8352601f198216937fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb591845b8681106119a05750836001959610611987575b505050811b01600d5580f35b015160001960f88460031b161c1916905538808061197b565b91926020600181928685015181550194019201611968565b600d8352611a00907fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5601f840160051c8101916020851061160557601f0160051c01906124ac565b38611903565b50346101b55760203660031901126101b557611a206122ce565b611a286125c3565b60018060a01b03166001600160601b0360a01b600654161760065580f35b50346101b55760203660031901126101b5576020611a74600435600052600060205260016040600020015490565b604051908152f35b50346101b55760203660031901126101b557606060c0604051611a9e81612330565b82815282602082015282604082015283838201528360808201528360a0820152015260043581526008602052604081209060405191611adc83612330565b604051611aed816106278185612429565b8352604051611b03816106278160018601612429565b6020840190815260405191611b2683611b1f8160028501612429565b0384612361565b6040850192835260ff6003820154169260608601936003811015611d6257845260048201549060808701918252600660018060a01b036005850154169360a08901948552019360405180958691602082549182815201918a5260208a20908a915b81601f8401106120495792611ca992611ce19592611cf49897955491818110612035575b81811061201e575b818110612007575b818110611ff0575b818110611fda575b818110611fc3575b818110611fac575b818110611f95575b818110611f7e575b818110611f67575b818110611f50575b818110611f39575b818110611f22575b818110611f0b575b818110611ef4575b818110611edd575b818110611ec6575b818110611eaf575b818110611e98575b818110611e81575b818110611e6a575b818110611e53575b818110611e3c575b818110611e25575b818110611e0e575b818110611df7575b818110611de0575b818110611dc9575b818110611db2575b818110611d9b575b818110611d84575b10611d76575b500388612361565b60c08a01968752611cce6040519a60208c525160e060208d01526101008c019061228d565b90518a8203601f190160408c015261228d565b9051888203601f190160608a015261228d565b93516003811015611d625760808701525160a0860152516001600160a01b031660c085015251838203601f190160e085015280518083528493602093840193909201915b818110611d46575050500390f35b825160ff16845285945060209384019390920191600101611d38565b634e487b7160e01b86526021600452602486fd5b60f81c815260200138611ca1565b92602060019160ff8560f01c168152019301611c9b565b92602060019160ff8560e81c168152019301611c93565b92602060019160ff8560e01c168152019301611c8b565b92602060019160ff8560d81c168152019301611c83565b92602060019160ff8560d01c168152019301611c7b565b92602060019160ff8560c81c168152019301611c73565b92602060019160ff8560c01c168152019301611c6b565b92602060019160ff8560b81c168152019301611c63565b92602060019160ff8560b01c168152019301611c5b565b92602060019160ff8560a81c168152019301611c53565b92602060019160ff8560a01c168152019301611c4b565b92602060019160ff8560981c168152019301611c43565b92602060019160ff8560901c168152019301611c3b565b92602060019160ff8560881c168152019301611c33565b92602060019160ff8560801c168152019301611c2b565b92602060019160ff8560781c168152019301611c23565b92602060019160ff8560701c168152019301611c1b565b92602060019160ff8560681c168152019301611c13565b92602060019160ff8560601c168152019301611c0b565b92602060019160ff8560581c168152019301611c03565b92602060019160ff8560501c168152019301611bfb565b92602060019160ff8560481c168152019301611bf3565b92602060019160ff8560401c168152019301611beb565b92602060019160ff8560381c168152019301611be3565b92602060019160ff8560301c168152019301611bdb565b92602060019160ff8560281c168152019301611bd3565b92602060019160ff85831c168152019301611bcb565b92602060019160ff8560181c168152019301611bc3565b92602060019160ff8560101c168152019301611bbb565b92602060019160ff8560081c168152019301611bb3565b92602060019160ff85168152019301611bab565b935090916001610400602092865460ff8116825260ff8160081c168583015260ff8160101c16604083015260ff8160181c16606083015260ff81861c16608083015260ff8160281c1660a083015260ff8160301c1660c083015260ff8160381c1660e083015260ff8160401c1661010083015260ff8160481c1661012083015260ff8160501c1661014083015260ff8160581c1661016083015260ff8160601c1661018083015260ff8160681c166101a083015260ff8160701c166101c083015260ff8160781c166101e083015260ff8160801c1661020083015260ff8160881c1661022083015260ff8160901c1661024083015260ff8160981c1661026083015260ff8160a01c1661028083015260ff8160a81c166102a083015260ff8160b01c166102c083015260ff8160b81c166102e083015260ff8160c01c1661030083015260ff8160c81c1661032083015260ff8160d01c1661034083015260ff8160d81c1661036083015260ff8160e01c1661038083015260ff8160e81c166103a083015260ff8160f01c166103c083015260f81c6103e0820152019401920190889392611b87565b50346101b557806003193601126101b5576006546040516001600160a01b039091168152602090f35b50346101b557806003193601126101b5576020600754604051908152f35b9050346113ff5760203660031901126113ff5760043563ffffffff60e01b811680910361046f5760209250637965db0b60e01b811490811561227c575b5015158152f35b6301ffc9a760e01b14905038612275565b919082519283825260005b8481106122b9575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201612298565b600435906001600160a01b03821682036122e457565b600080fd5b602435906001600160a01b03821682036122e457565b600a5481101561231a57600a60005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b60e081019081106001600160401b0382111761234b57604052565b634e487b7160e01b600052604160045260246000fd5b90601f801991011681019081106001600160401b0382111761234b57604052565b81601f820112156122e4578035906001600160401b03821161234b57604051926123b6601f8401601f191660200185612361565b828452602083830101116122e457816000926020809301838601378301015290565b6001600160401b03811161234b5760051b60200190565b90600182811c9216801561241f575b602083101461240957565b634e487b7160e01b600052602260045260246000fd5b91607f16916123fe565b60009291815491612439836123ef565b808352926001811690811561248f575060011461245557505050565b60009081526020812093945091925b838310612475575060209250010190565b600181602092949394548385870101520191019190612464565b915050602093945060ff929192191683830152151560051b010190565b8181106124b7575050565b600081556001016124ac565b9190601f81116124d257505050565b6124fd926000526020600020906020601f840160051c8301931061160557601f0160051c01906124ac565b565b1561250657565b60405162461bcd60e51b815260206004820152600e60248201526d31b0b73737ba103932b2b73a32b960911b6044820152606490fd5b1561254357565b60405162461bcd60e51b815260206004820152600c60248201526b2737ba10383937b837b9b2b960a11b6044820152606490fd5b1561257e57565b60405162461bcd60e51b815260206004820152601960248201527f4170706c69636174696f6e206973206e6f7420616374697665000000000000006044820152606490fd5b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16156125fc57565b63e2517d3f60e01b60005233600452600060245260446000fd5b60008181526020818152604080832033845290915290205460ff16156126395750565b63e2517d3f60e01b6000523360045260245260446000fd5b60405163a9059cbb60e01b60208201526001600160a01b0390921660248301526044808301939093529181526124fd91610e00606483612361565b6001600160a01b03811660009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff16612738576001600160a01b031660008181527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560205260408120805460ff191660011790553391907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a4600190565b50600090565b6000818152602081815260408083206001600160a01b038616845290915290205460ff166127c2576000818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b5050600090565b6000818152602081815260408083206001600160a01b038616845290915290205460ff16156127c2576000818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b60ff6001541661285757565b63d93c066560e01b60005260046000fd5b906000602091828151910182855af1156128c3576000513d6128ba57506001600160a01b0381163b155b6128995750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b60011415612892565b6040513d6000823e3d90fdfef0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a264697066735822122092d21f722413106e34835bf19607b553546784a20a8755d5d9dd69dcab773aa164736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ 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.