Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Will
- Optimization enabled
- true
- Compiler version
- v0.8.25+commit.b61c2a91
- Optimization runs
- 800
- EVM Version
- paris
- Verified at
- 2024-10-31T15:23:11.988247Z
Constructor Arguments
0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c9a9c487bb6f53ba8abe8471d39358c875b388c500000000000000000000000032e3c7fd24e175701a35c224f2238d18439c7dbc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000000000000000000000009195731e2ce35eb000000
src/Will.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.3; import {ERC20ASG} from "ERC20ASG/src/ERC20ASG.sol"; import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol"; import {SuperchainERC20} from "./components/SuperchainERC20.sol"; import {IFun} from "./interfaces/IFun.sol"; /// @title Root Value Token /// @author Bogdan A. | parseb /// @notice this is the token of the protocol contract Will is SuperchainERC20, ERC20ASG { bool entered; constructor(uint256 price_, uint256 pps_, address[] memory initMintAddrs_, uint256[] memory initMintAmts_) ERC20ASG("WILL Root Value Token", "WRVT", price_, pps_, initMintAddrs_, initMintAmts_) {} error ATransferFailed(); error InsufficentBalance(); error OnlyFun(); error PingF(); error PayCallF(); error Reentrant(); error UnqualifiedCall(); error DelegateCallFailed(); error InvalidCalldata(); /// @notice burns amount of token and retrieves underlying value as well as corresponding share of specified tokens /// @param amountToBurn_ how much of it to prove /// @param tokensToRedeem list of tokens to withdraw from pool function deconstructBurn(uint256 amountToBurn_, address[] memory tokensToRedeem) external returns (uint256 shareBurned) { if (balanceOf(msg.sender) < amountToBurn_) revert InsufficentBalance(); shareBurned = totalSupply() / amountToBurn_; _burn(msg.sender, amountToBurn_); if (entered) revert Reentrant(); entered = true; uint256 i; bool s = true; for (i; i < tokensToRedeem.length;) { IERC20 T = IERC20(tokensToRedeem[i]); amountToBurn_ = T.balanceOf(address(this)); if (s) s = s && T.transfer(msg.sender, (amountToBurn_ / shareBurned)); if (!s) revert ATransferFailed(); unchecked { ++i; } } (s,) = payable(msg.sender).call{value: address(this).balance / shareBurned}(""); if (!s) revert PayCallF(); delete entered; } function simpleBurn(uint256 amountToBurn_) external returns (uint256 amtValReturned) { if (balanceOf(msg.sender) < amountToBurn_) revert InsufficentBalance(); amtValReturned = burn(amountToBurn_); } function mintFromETH() public payable returns (uint256 howMuchMinted) { howMuchMinted = msg.value / currentPrice(); mint(howMuchMinted); } receive() external payable { mintFromETH(); } fallback() external payable { // Check if sender has a bigger balance than 69% of supply if (balanceOf(msg.sender) <= (totalSupply() * 77) / 100) revert UnqualifiedCall(); // Check if the function signature is delegatecall() if (bytes4(msg.data) == bytes4(keccak256("delegatecall()"))) { if (msg.data.length < 24) revert InvalidCalldata(); // Extract target address and calldata (address target, bytes memory callData) = abi.decode(msg.data[4:], (address, bytes)); // Execute delegatecall (bool success,) = target.delegatecall(callData); if (!success) revert DelegateCallFailed(); } } }
lib/openzeppelin-contracts/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * 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[EIP 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); }
lib/ERC20ASG/src/ERC20ASG.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.25; import {IERC20ASG} from "./IERC20ASG.sol"; import {ERC20} from "openzeppelin-contracts/token/ERC20/ERC20.sol"; //// @notice ERC20GM: Fungible, Uncapped ETH Dutch Auction /// @author parseb contract ERC20ASG is ERC20, IERC20ASG { //// price amount uint256 immutable price; uint256 public immutable initTime; uint256 public immutable pps; ////////////////// Errors error ValueMismatch(); error BurnRefundF(); ////////////////// External //// @notice constructor function instantiates immutable contract instance //// @param name_ wanted name of token //// @param symbol_ wanted symbol of token //// @param price_ wanted starting price in giga-wei //// @param pps_ wanted linear price increase in wei per second constructor( string memory name_, string memory symbol_, uint256 price_, uint256 pps_, address[] memory initMintAddrs_, uint256[] memory initMintAmts_ ) ERC20(name_, symbol_) { price = price_ == 0 ? ((uint256(uint160(bytes20(address(this))) % 10)) + 1 gwei) : price_ * 1 gwei; pps = pps_ == 0 ? 1 gwei : pps_; initTime = block.timestamp; if (initMintAddrs_.length > 0 && initMintAmts_[0] > 0) { price_ = 0; for (price_; price_ < initMintAddrs_.length;) { if (initMintAddrs_[price_] == address(0) || initMintAmts_[price_] == 0) continue; _mint(initMintAddrs_[price_], initMintAmts_[price_]); unchecked { ++price_; } } } } //// @inheritdoc IERC20GM function mint(uint256 howMany_) public payable { if (msg.value < mintCost(howMany_)) revert ValueMismatch(); _mint(msg.sender, howMany_); } //// @inheritdoc IERC20GM function burn(uint256 howMany_) public override returns (uint256 amtValReturned) { amtValReturned = burnReturns(howMany_); _burn(msg.sender, howMany_); (bool s,) = msg.sender.call{value: amtValReturned}(""); if (!s) revert BurnRefundF(); } //// @inheritdoc IERC20GM function burnTo(uint256 howMany_, address to_) public returns (uint256 amount) { amount = burnReturns(howMany_); _burn(msg.sender, howMany_); (bool s,) = to_.call{value: amount}(""); if (!s) revert BurnRefundF(); } //// @notice returns current price per unit function currentPrice() public view returns (uint256) { return (price + (pps * (block.timestamp - initTime))); } //// @inheritdoc IERC20GM function mintCost(uint256 amt_) public view returns (uint256) { return currentPrice() * amt_; } //// @inheritdoc IERC20GM function burnReturns(uint256 amt_) public view returns (uint256 rv) { if (totalSupply() > 0) rv = amt_ * address(this).balance / totalSupply(); } }
lib/ERC20ASG/src/IERC20ASG.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.25; import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol"; interface IERC20ASG is IERC20 { //// @notice mints specified amount to msg.sender requires corresponding value //// @param howMany_ number of tokens wanted function mint(uint256 howMany_) external payable; //// @notice burns amount provided sender has balanace. returns coresponding available value. //// @param howMany_ amount to burn // function burn(uint256 howMany_) external returns (uint256 amtValReturned); //// @notice returns current mint price per full unit function currentPrice() external view returns (uint256); //// @notice returns cost for mint for amount at current block //// @param amt_ amount of units to calculate price for function mintCost(uint256 amt_) external view returns (uint256); //// @notice returns amount of ETH refunded for burining the provided amount //// @param amt_ amount to calculate refund from expressed as a full, non-fractionable unit (1e18) function burnReturns(uint256 amt_) external view returns (uint256); //// @param howMany_ how many of full units to burn expressed as full units (1e18 min) //// @param to_ address to send refund to //// @dev note that only full units are supported and full unit burn wrapper might be needed for fractional burn function burnTo(uint256 howMany_, address to_) external returns (uint256); //// @param howMany_ how many of full units to burn expressed as full units (1e18 min) //// @dev note that only full units are supported and full unit burn wrapper might be needed for fractional burn function burn(uint256 howMany_) external returns (uint256); }
lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} }
lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ 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 amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` 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 amount) external returns (bool); }
lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ 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); }
lib/optimism/packages/contracts-bedrock/src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title IL2ToL2CrossDomainMessenger /// @notice Interface for the L2ToL2CrossDomainMessenger contract. interface IL2ToL2CrossDomainMessenger { /// @notice Mapping of message hashes to boolean receipt values. Note that a message will only /// be present in this mapping if it has successfully been relayed on this chain, and /// can therefore not be relayed again. /// @param _msgHash message hash to check. /// @return Returns true if the message corresponding to the `_msgHash` was successfully relayed. function successfulMessages(bytes32 _msgHash) external view returns (bool); /// @notice Retrieves the next message nonce. Message version will be added to the upper two /// bytes of the message nonce. Message version allows us to treat messages as having /// different structures. /// @return Nonce of the next message to be sent, with added message version. function messageNonce() external view returns (uint256); /// @notice Retrieves the sender of the current cross domain message. /// @return _sender Address of the sender of the current cross domain message. function crossDomainMessageSender() external view returns (address _sender); /// @notice Retrieves the source of the current cross domain message. /// @return _source Chain ID of the source of the current cross domain message. function crossDomainMessageSource() external view returns (uint256 _source); /// @notice Sends a message to some target address on a destination chain. Note that if the call /// always reverts, then the message will be unrelayable, and any ETH sent will be /// permanently locked. The same will occur if the target on the other chain is /// considered unsafe (see the _isUnsafeTarget() function). /// @param _destination Chain ID of the destination chain. /// @param _target Target contract or wallet address. /// @param _message Message to trigger the target address with. function sendMessage(uint256 _destination, address _target, bytes calldata _message) external; /// @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only /// be executed via cross-chain call from the other messenger OR if the message was /// already received once and is currently being replayed. /// @param _destination Chain ID of the destination chain. /// @param _nonce Nonce of the message being relayed. /// @param _sender Address of the user who sent the message. /// @param _source Chain ID of the source chain. /// @param _target Address that the message is targeted at. /// @param _message Message to send to the target. function relayMessage( uint256 _destination, uint256 _source, uint256 _nonce, address _sender, address _target, bytes calldata _message ) external payable; }
lib/optimism/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // Interfaces import { IERC20Solady } from "src/vendor/interfaces/IERC20Solady.sol"; /// @title ISuperchainERC20Extensions /// @notice Interface for the extensions to the ERC20 standard that are used by SuperchainERC20. /// Exists in case developers are already importing the ERC20 interface separately and /// importing the full SuperchainERC20 interface would cause conflicting imports. interface ISuperchainERC20Extensions { /// @notice Emitted when tokens are sent from one chain to another. /// @param from Address of the sender. /// @param to Address of the recipient. /// @param amount Number of tokens sent. /// @param destination Chain ID of the destination chain. event SendERC20(address indexed from, address indexed to, uint256 amount, uint256 destination); /// @notice Emitted whenever tokens are successfully relayed on this chain. /// @param from Address of the msg.sender of sendERC20 on the source chain. /// @param to Address of the recipient. /// @param amount Amount of tokens relayed. /// @param source Chain ID of the source chain. event RelayERC20(address indexed from, address indexed to, uint256 amount, uint256 source); /// @notice Sends tokens to some target address on another chain. /// @param _to Address to send tokens to. /// @param _amount Amount of tokens to send. /// @param _chainId Chain ID of the destination chain. function sendERC20(address _to, uint256 _amount, uint256 _chainId) external; /// @notice Relays tokens received from another chain. /// @param _from Address of the msg.sender of sendERC20 on the source chain. /// @param _to Address to relay tokens to. /// @param _amount Amount of tokens to relay. function relayERC20(address _from, address _to, uint256 _amount) external; } /// @title ISuperchainERC20Errors /// @notice Interface containing the errors added in the SuperchainERC20 implementation. interface ISuperchainERC20Errors { /// @notice Thrown when attempting to relay a message and the function caller (msg.sender) is not /// L2ToL2CrossDomainMessenger. error CallerNotL2ToL2CrossDomainMessenger(); /// @notice Thrown when attempting to relay a message and the cross domain message sender is not this /// SuperchainERC20. error InvalidCrossDomainSender(); /// @notice Thrown when attempting to perform an operation and the account is the zero address. error ZeroAddress(); } /// @title ISuperchainERC20 /// @notice Combines Solady's ERC20 interface with the SuperchainERC20Extensions interface. interface ISuperchainERC20 is IERC20Solady, ISuperchainERC20Extensions, ISuperchainERC20Errors { }
lib/optimism/packages/contracts-bedrock/src/libraries/Predeploys.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title Predeploys /// @notice Contains constant addresses for protocol contracts that are pre-deployed to the L2 system. // This excludes the preinstalls (non-protocol contracts). library Predeploys { /// @notice Number of predeploy-namespace addresses reserved for protocol usage. uint256 internal constant PREDEPLOY_COUNT = 2048; /// @custom:legacy /// @notice Address of the LegacyMessagePasser predeploy. Deprecate. Use the updated /// L2ToL1MessagePasser contract instead. address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000; /// @custom:legacy /// @notice Address of the L1MessageSender predeploy. Deprecated. Use L2CrossDomainMessenger /// or access tx.origin (or msg.sender) in a L1 to L2 transaction instead. /// Not embedded into new OP-Stack chains. address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001; /// @custom:legacy /// @notice Address of the DeployerWhitelist predeploy. No longer active. address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002; /// @notice Address of the canonical WETH contract. address internal constant WETH = 0x4200000000000000000000000000000000000006; /// @notice Address of the L2CrossDomainMessenger predeploy. address internal constant L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007; /// @notice Address of the GasPriceOracle predeploy. Includes fee information /// and helpers for computing the L1 portion of the transaction fee. address internal constant GAS_PRICE_ORACLE = 0x420000000000000000000000000000000000000F; /// @notice Address of the L2StandardBridge predeploy. address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010; //// @notice Address of the SequencerFeeWallet predeploy. address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011; /// @notice Address of the OptimismMintableERC20Factory predeploy. address internal constant OPTIMISM_MINTABLE_ERC20_FACTORY = 0x4200000000000000000000000000000000000012; /// @custom:legacy /// @notice Address of the L1BlockNumber predeploy. Deprecated. Use the L1Block predeploy /// instead, which exposes more information about the L1 state. address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013; /// @notice Address of the L2ERC721Bridge predeploy. address internal constant L2_ERC721_BRIDGE = 0x4200000000000000000000000000000000000014; /// @notice Address of the L1Block predeploy. address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015; /// @notice Address of the L2ToL1MessagePasser predeploy. address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000016; /// @notice Address of the OptimismMintableERC721Factory predeploy. address internal constant OPTIMISM_MINTABLE_ERC721_FACTORY = 0x4200000000000000000000000000000000000017; /// @notice Address of the ProxyAdmin predeploy. address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018; /// @notice Address of the BaseFeeVault predeploy. address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019; /// @notice Address of the L1FeeVault predeploy. address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A; /// @notice Address of the SchemaRegistry predeploy. address internal constant SCHEMA_REGISTRY = 0x4200000000000000000000000000000000000020; /// @notice Address of the EAS predeploy. address internal constant EAS = 0x4200000000000000000000000000000000000021; /// @notice Address of the GovernanceToken predeploy. address internal constant GOVERNANCE_TOKEN = 0x4200000000000000000000000000000000000042; /// @custom:legacy /// @notice Address of the LegacyERC20ETH predeploy. Deprecated. Balances are migrated to the /// state trie as of the Bedrock upgrade. Contract has been locked and write functions /// can no longer be accessed. address internal constant LEGACY_ERC20_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000; /// @notice Address of the CrossL2Inbox predeploy. address internal constant CROSS_L2_INBOX = 0x4200000000000000000000000000000000000022; /// @notice Address of the L2ToL2CrossDomainMessenger predeploy. address internal constant L2_TO_L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000023; /// @notice Address of the SuperchainWETH predeploy. address internal constant SUPERCHAIN_WETH = 0x4200000000000000000000000000000000000024; /// @notice Address of the ETHLiquidity predeploy. address internal constant ETH_LIQUIDITY = 0x4200000000000000000000000000000000000025; /// @notice Address of the OptimismSuperchainERC20Factory predeploy. address internal constant OPTIMISM_SUPERCHAIN_ERC20_FACTORY = 0x4200000000000000000000000000000000000026; /// @notice Address of the OptimismSuperchainERC20Beacon predeploy. address internal constant OPTIMISM_SUPERCHAIN_ERC20_BEACON = 0x4200000000000000000000000000000000000027; // TODO: Precalculate the address of the implementation contract /// @notice Arbitrary address of the OptimismSuperchainERC20 implementation contract. address internal constant OPTIMISM_SUPERCHAIN_ERC20 = 0xB9415c6cA93bdC545D4c5177512FCC22EFa38F28; /// @notice Returns the name of the predeploy at the given address. function getName(address _addr) internal pure returns (string memory out_) { require(isPredeployNamespace(_addr), "Predeploys: address must be a predeploy"); if (_addr == LEGACY_MESSAGE_PASSER) return "LegacyMessagePasser"; if (_addr == L1_MESSAGE_SENDER) return "L1MessageSender"; if (_addr == DEPLOYER_WHITELIST) return "DeployerWhitelist"; if (_addr == WETH) return "WETH"; if (_addr == L2_CROSS_DOMAIN_MESSENGER) return "L2CrossDomainMessenger"; if (_addr == GAS_PRICE_ORACLE) return "GasPriceOracle"; if (_addr == L2_STANDARD_BRIDGE) return "L2StandardBridge"; if (_addr == SEQUENCER_FEE_WALLET) return "SequencerFeeVault"; if (_addr == OPTIMISM_MINTABLE_ERC20_FACTORY) return "OptimismMintableERC20Factory"; if (_addr == L1_BLOCK_NUMBER) return "L1BlockNumber"; if (_addr == L2_ERC721_BRIDGE) return "L2ERC721Bridge"; if (_addr == L1_BLOCK_ATTRIBUTES) return "L1Block"; if (_addr == L2_TO_L1_MESSAGE_PASSER) return "L2ToL1MessagePasser"; if (_addr == OPTIMISM_MINTABLE_ERC721_FACTORY) return "OptimismMintableERC721Factory"; if (_addr == PROXY_ADMIN) return "ProxyAdmin"; if (_addr == BASE_FEE_VAULT) return "BaseFeeVault"; if (_addr == L1_FEE_VAULT) return "L1FeeVault"; if (_addr == SCHEMA_REGISTRY) return "SchemaRegistry"; if (_addr == EAS) return "EAS"; if (_addr == GOVERNANCE_TOKEN) return "GovernanceToken"; if (_addr == LEGACY_ERC20_ETH) return "LegacyERC20ETH"; if (_addr == CROSS_L2_INBOX) return "CrossL2Inbox"; if (_addr == L2_TO_L2_CROSS_DOMAIN_MESSENGER) return "L2ToL2CrossDomainMessenger"; if (_addr == SUPERCHAIN_WETH) return "SuperchainWETH"; if (_addr == ETH_LIQUIDITY) return "ETHLiquidity"; if (_addr == OPTIMISM_SUPERCHAIN_ERC20_FACTORY) return "OptimismSuperchainERC20Factory"; if (_addr == OPTIMISM_SUPERCHAIN_ERC20_BEACON) return "OptimismSuperchainERC20Beacon"; revert("Predeploys: unnamed predeploy"); } /// @notice Returns true if the predeploy is not proxied. function notProxied(address _addr) internal pure returns (bool) { return _addr == GOVERNANCE_TOKEN || _addr == WETH; } /// @notice Returns true if the address is a defined predeploy that is embedded into new OP-Stack chains. function isSupportedPredeploy(address _addr, bool _useInterop) internal pure returns (bool) { return _addr == LEGACY_MESSAGE_PASSER || _addr == DEPLOYER_WHITELIST || _addr == WETH || _addr == L2_CROSS_DOMAIN_MESSENGER || _addr == GAS_PRICE_ORACLE || _addr == L2_STANDARD_BRIDGE || _addr == SEQUENCER_FEE_WALLET || _addr == OPTIMISM_MINTABLE_ERC20_FACTORY || _addr == L1_BLOCK_NUMBER || _addr == L2_ERC721_BRIDGE || _addr == L1_BLOCK_ATTRIBUTES || _addr == L2_TO_L1_MESSAGE_PASSER || _addr == OPTIMISM_MINTABLE_ERC721_FACTORY || _addr == PROXY_ADMIN || _addr == BASE_FEE_VAULT || _addr == L1_FEE_VAULT || _addr == SCHEMA_REGISTRY || _addr == EAS || _addr == GOVERNANCE_TOKEN || (_useInterop && _addr == CROSS_L2_INBOX) || (_useInterop && _addr == L2_TO_L2_CROSS_DOMAIN_MESSENGER) || (_useInterop && _addr == SUPERCHAIN_WETH) || (_useInterop && _addr == ETH_LIQUIDITY) || (_useInterop && _addr == OPTIMISM_SUPERCHAIN_ERC20_FACTORY) || (_useInterop && _addr == OPTIMISM_SUPERCHAIN_ERC20_BEACON); } function isPredeployNamespace(address _addr) internal pure returns (bool) { return uint160(_addr) >> 11 == uint160(0x4200000000000000000000000000000000000000) >> 11; } /// @notice Function to compute the expected address of the predeploy implementation /// in the genesis state. function predeployToCodeNamespace(address _addr) internal pure returns (address) { require( isPredeployNamespace(_addr), "Predeploys: can only derive code-namespace address for predeploy addresses" ); return address( uint160(uint256(uint160(_addr)) & 0xffff | uint256(uint160(0xc0D3C0d3C0d3C0D3c0d3C0d3c0D3C0d3c0d30000))) ); } }
lib/optimism/packages/contracts-bedrock/src/vendor/interfaces/IERC20Solady.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC20Solady { /// @dev The total supply has overflowed. error TotalSupplyOverflow(); /// @dev The allowance has overflowed. error AllowanceOverflow(); /// @dev The allowance has underflowed. error AllowanceUnderflow(); /// @dev Insufficient balance. error InsufficientBalance(); /// @dev Insufficient allowance. error InsufficientAllowance(); /// @dev The permit is invalid. error InvalidPermit(); /// @dev The permit has expired. error PermitExpired(); /// @dev Emitted when `amount` tokens is transferred from `from` to `to`. event Transfer(address indexed from, address indexed to, uint256 amount); /// @dev Emitted when `amount` tokens is approved by `owner` to be used by `spender`. event Approval(address indexed owner, address indexed spender, uint256 amount); /// @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); /// @dev Returns the amount of tokens in existence. function totalSupply() external view returns (uint256 result); /// @dev Returns the amount of tokens owned by `owner` function balanceOf(address owner) external view returns (uint256 result); /// @dev Returns the amount of tokens that `spender` can spend on behalf of `owner`. function allowance(address owner, address spender) external view returns (uint256 result); /// @dev Sets `amount` as the allowance of `spender` over the caller's tokens. /// /// Emits a {Approval} event. function approve(address spender, uint256 amount) external returns (bool); /// @dev Transfer `amount` tokens from the caller to `to`. /// /// Requirements: /// - `from` must at least have `amount`. /// /// Emits a {Transfer} event. function transfer(address to, uint256 amount) external returns (bool); /// @dev Transfers `amount` tokens from `from` to `to`. /// /// Note: Does not update the allowance if it is the maximum uint256 value. /// /// Requirements: /// - `from` must at least have `amount`. /// - The caller must have at least `amount` of allowance to transfer the tokens of `from`. /// /// Emits a {Transfer} event. function transferFrom(address from, address to, uint256 amount) external returns (bool); /// @dev Returns the current nonce for `owner`. /// This value is used to compute the signature for EIP-2612 permit. function nonces(address owner) external view returns (uint256 result); /// @dev Sets `value` as the allowance of `spender` over the tokens of `owner`, /// authorized by a signed approval by `owner`. /// /// Emits a {Approval} event. function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /// @dev Returns the EIP-712 domain separator for the EIP-2612 permit. function DOMAIN_SEPARATOR() external view returns (bytes32 result); }
src/components/SuperchainERC20.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.25; import { ISuperchainERC20Extensions, ISuperchainERC20Errors } from "optimism/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol"; // import { ERC20 } from "@solady/tokens/ERC20.sol"; import {IL2ToL2CrossDomainMessenger} from "optimism/packages/contracts-bedrock/src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; import {Predeploys} from "optimism/packages/contracts-bedrock/src/libraries/Predeploys.sol"; import {ERC20} from "openzeppelin-contracts/token/ERC20/ERC20.sol"; /// @title SuperchainERC20 /// @notice SuperchainERC20 is a standard extension of the base ERC20 token contract that unifies ERC20 token /// bridging to make it fungible across the Superchain. It builds on top of the L2ToL2CrossDomainMessenger for /// both replay protection and domain binding. abstract contract SuperchainERC20 is ISuperchainERC20Extensions, ISuperchainERC20Errors, ERC20 { /// @notice Address of the L2ToL2CrossDomainMessenger Predeploy. address internal constant MESSENGER = Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER; /// @notice Sends tokens to some target address on another chain. /// @param _to Address to send tokens to. /// @param _amount Amount of tokens to send. /// @param _chainId Chain ID of the destination chain. function sendERC20(address _to, uint256 _amount, uint256 _chainId) external virtual { if (_to == address(0)) revert ZeroAddress(); _burn(msg.sender, _amount); bytes memory _message = abi.encodeCall(this.relayERC20, (msg.sender, _to, _amount)); IL2ToL2CrossDomainMessenger(MESSENGER).sendMessage(_chainId, address(this), _message); emit SendERC20(msg.sender, _to, _amount, _chainId); } /// @notice Relays tokens received from another chain. /// @param _from Address of the msg.sender of sendERC20 on the source chain. /// @param _to Address to relay tokens to. /// @param _amount Amount of tokens to relay. function relayERC20(address _from, address _to, uint256 _amount) external virtual { if (msg.sender != MESSENGER) revert CallerNotL2ToL2CrossDomainMessenger(); if (IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSender() != address(this)) { revert InvalidCrossDomainSender(); } uint256 source = IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSource(); _mint(_to, _amount); emit RelayERC20(_from, _to, _amount, source); } }
src/interfaces/IExecution.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.3; enum SQState { None, Initialized, Valid, Executed, Stale } enum MovementType { Revert, AgentMajority, EnergeticMajority } struct Call { address target; bytes callData; } struct Movement { MovementType category; address initiatior; address exeAccount; uint256 viaNode; uint256 expiresAt; bytes32 descriptionHash; bytes executedPayload; } struct SignatureQueue { SQState state; Movement Action; address[] Signers; bytes[] Sigs; bytes32 exeSig; } struct UserSignal { string[2][] MembraneInflation; string[] lastRedistSignal; } struct NodeState { string[9] basicInfo; // [nodeId, inflation, balanceAnchor, balanceBudget, value, membraneId, balanceOfUser, childParentEligibilityPerSec, lastParentRedistribution ] string membraneMeta; address[] membersOfNode; string[] childrenNodes; string[] rootPath; UserSignal[] signals; } interface IExecution { function createEndpointForOwner(address origin, uint256 nodeId_, address owner) external returns (address endpoint); function executeQueue(bytes32 SignatureQueueHash_) external returns (bool s); function submitSignatures(bytes32 sigHash, address[] memory signers, bytes[] memory signatures) external; function startMovement( address origin, uint8 typeOfMovement, uint256 node_, uint256 expiresInDays, address executingAccount, bytes32 descriptionHash, bytes memory data ) external returns (bytes32 movementHash); function setWillWe(address WillWeImplementationAddress) external; /// View function isQueueValid(bytes32 sigHash) external view returns (bool); function FoundingAgent() external returns (address); function WillToken() external view returns (address); function getSigQueue(bytes32 hash_) external view returns (SignatureQueue memory); /// @notice retrieves the node or agent that owns the execution account /// @param endpointAddress execution account for which to retrieve owner /// @dev in case of user-driven endpoints the returned value is uint160( address of endpoint creator ) function endpointOwner(address endpointAddress) external view returns (uint256); function isValidSignature(bytes32 _hash, bytes memory _signature) external view returns (bytes4); function hashMessage(Movement memory movement) external view returns (bytes32); //// cleanup functions function removeSignature(bytes32 sigHash_, uint256 index_, address who_) external; function removeLatentAction(bytes32 actionHash_, uint256 index) external; }
src/interfaces/IFun.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.3; import {IERC1155} from "openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol"; import {IExecution, SignatureQueue, NodeState} from "./IExecution.sol"; interface IFun is IERC1155, IExecution { function spawnRootBranch(address fungible20_) external returns (uint256 fID); function spawnBranch(uint256 fid_) external returns (uint256 newID); function spawnBranchWithMembrane(uint256 fid_, uint256 membraneID_) external returns (uint256 newID); function mintMembership(uint256 fid_, address to_) external returns (uint256 mID); function membershipEnforce(address target, uint256 fid_) external returns (bool s); function burn(uint256 fid_, uint256 amount_) external; function allMembersOf(uint256 fid_) external view returns (address[] memory); function mint(uint256 fid_, uint256 amount_) external; function toID(address x) external view returns (uint256); function toAddress(uint256 x) external view returns (address); function isMember(address whoabout_, uint256 whereabout_) external view returns (bool); function getInUseMemberaneID(uint256 fid_) external view returns (uint256 membraneID_); function getMembraneOf(uint256 fid_) external view returns (uint256); function getChildrenOf(uint256 fid_) external view returns (uint256[] memory); function getParentOf(uint256 fid_) external view returns (uint256); function membershipID(uint256 fid_) external pure returns (uint256); function getRootId(uint256 fid_) external view returns (uint256); function getRootToken(uint256 fid_) external view returns (address); function fungo() external returns (address); function createEndpointForOwner(uint256 nodeId_, address owner) external returns (address endpoint); function localizeEndpoint(address endpointAddress, uint256 endpointParent_, address endpointOwner_) external; function getSigQueue(bytes32 hash_) external view returns (SignatureQueue memory); function totalSupply(uint256 nodeId) external view returns (uint256); function executionEngineAddress() external view returns (address); function rule() external; function Will() external view returns (address); function getUserInteractions(address user_) external view returns (uint256[][2] memory); function removeSignature(bytes32 sigHash_, uint256 index_) external; function inParentDenomination(uint256 amt_, uint256 id_) external view returns (uint256); function getFidPath(uint256 fid_) external view returns (uint256[] memory fids); function burnPath(uint256 target_, uint256 amount) external; function mintPath(uint256 target_, uint256 amount) external; function sendSignal(uint256 targetNode_, uint256[] memory signals) external; function initSelfControl() external returns (address controlingAgent); //// Data function getNodeData(uint256 n) external view returns (NodeState memory N); function getNodes(uint256[] memory nodeIds) external view returns (NodeState[] memory nodes); function getAllNodesForRoot(address rootAddress, address userIfAny) external view returns (NodeState[] memory nodes); }
Compiler Settings
{"viaIR":false,"remappings":["openzeppelin-contracts/token/=lib/openzeppelin-contracts/contracts/token/","openzeppelin-contracts/contracts/=lib/openzeppelin-contracts/contracts/","@solady/=lib/solady/src/","src/vendor/interfaces/=lib/optimism/packages/contracts-bedrock/src/vendor/interfaces/","@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/","ERC20ASG/=lib/ERC20ASG/","automate/=lib/optimism/packages/contracts-bedrock/lib/automate/contracts/","ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/halmos-cheatcodes/src/","kontrol-cheatcodes/=lib/optimism/packages/contracts-bedrock/lib/kontrol-cheatcodes/src/","lib-keccak/=lib/optimism/packages/contracts-bedrock/lib/lib-keccak/contracts/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts-v5/=lib/optimism/packages/contracts-bedrock/lib/openzeppelin-contracts-v5/","openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/","openzeppelin/=lib/openzeppelin-contracts/contracts/","optimism/=lib/optimism/","prb-test/=lib/optimism/packages/contracts-bedrock/lib/automate/lib/prb-test/src/","safe-contracts/=lib/optimism/packages/contracts-bedrock/lib/safe-contracts/contracts/","solady/=lib/solady/src/","solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/","solmate/=lib/optimism/packages/contracts-bedrock/lib/solmate/src/"],"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","storageLayout"],"":["ast"]}},"optimizer":{"runs":800,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"uint256","name":"price_","internalType":"uint256"},{"type":"uint256","name":"pps_","internalType":"uint256"},{"type":"address[]","name":"initMintAddrs_","internalType":"address[]"},{"type":"uint256[]","name":"initMintAmts_","internalType":"uint256[]"}]},{"type":"error","name":"ATransferFailed","inputs":[]},{"type":"error","name":"BurnRefundF","inputs":[]},{"type":"error","name":"CallerNotL2ToL2CrossDomainMessenger","inputs":[]},{"type":"error","name":"DelegateCallFailed","inputs":[]},{"type":"error","name":"InsufficentBalance","inputs":[]},{"type":"error","name":"InvalidCalldata","inputs":[]},{"type":"error","name":"InvalidCrossDomainSender","inputs":[]},{"type":"error","name":"OnlyFun","inputs":[]},{"type":"error","name":"PayCallF","inputs":[]},{"type":"error","name":"PingF","inputs":[]},{"type":"error","name":"Reentrant","inputs":[]},{"type":"error","name":"UnqualifiedCall","inputs":[]},{"type":"error","name":"ValueMismatch","inputs":[]},{"type":"error","name":"ZeroAddress","inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RelayERC20","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"source","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SendERC20","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"destination","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"fallback","stateMutability":"payable"},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amtValReturned","internalType":"uint256"}],"name":"burn","inputs":[{"type":"uint256","name":"howMany_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"rv","internalType":"uint256"}],"name":"burnReturns","inputs":[{"type":"uint256","name":"amt_","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"}],"name":"burnTo","inputs":[{"type":"uint256","name":"howMany_","internalType":"uint256"},{"type":"address","name":"to_","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"shareBurned","internalType":"uint256"}],"name":"deconstructBurn","inputs":[{"type":"uint256","name":"amountToBurn_","internalType":"uint256"},{"type":"address[]","name":"tokensToRedeem","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"initTime","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"mint","inputs":[{"type":"uint256","name":"howMany_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"mintCost","inputs":[{"type":"uint256","name":"amt_","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256","name":"howMuchMinted","internalType":"uint256"}],"name":"mintFromETH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pps","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"relayERC20","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"sendERC20","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"uint256","name":"_chainId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amtValReturned","internalType":"uint256"}],"name":"simpleBurn","inputs":[{"type":"uint256","name":"amountToBurn_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x60e060405234801561001057600080fd5b506040516120d53803806120d583398101604081905261002f91610390565b6040518060400160405280601581526020017f57494c4c20526f6f742056616c756520546f6b656e00000000000000000000008152506040518060400160405280600481526020016315d4959560e21b81525085858585858581600390816100979190610500565b5060046100a48282610500565b505050836000146100c2576100bd84633b9aca006105d5565b6100e4565b6100cd600a306105f2565b6100e4906001600160a01b0316633b9aca00610626565b60805282156100f357826100f9565b633b9aca005b60c0524260a05281511580159061012a575060008160008151811061012057610120610639565b6020026020010151115b156101e157600093505b81518410156101e15760006001600160a01b031682858151811061015a5761015a610639565b60200260200101516001600160a01b03161480610190575080848151811061018457610184610639565b60200260200101516000145b610134576101d68285815181106101a9576101a9610639565b60200260200101518286815181106101c3576101c3610639565b60200260200101516101f060201b60201c565b836001019350610134565b5050505050505050505061064f565b6001600160a01b03821661024a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b806002600082825461025c9190610626565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156102f6576102f66102b8565b604052919050565b60006001600160401b03821115610317576103176102b8565b5060051b60200190565b600082601f83011261033257600080fd5b81516020610347610342836102fe565b6102ce565b8083825260208201915060208460051b87010193508684111561036957600080fd5b602086015b84811015610385578051835291830191830161036e565b509695505050505050565b600080600080608085870312156103a657600080fd5b845160208087015160408801519296509450906001600160401b03808211156103ce57600080fd5b818801915088601f8301126103e257600080fd5b81516103f0610342826102fe565b81815260059190911b8301840190848101908b83111561040f57600080fd5b938501935b828510156104435784516001600160a01b03811681146104345760008081fd5b82529385019390850190610414565b60608b0151909750945050508083111561045c57600080fd5b505061046a87828801610321565b91505092959194509250565b600181811c9082168061048a57607f821691505b6020821081036104aa57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156102b3576000816000526020600020601f850160051c810160208610156104d95750805b601f850160051c820191505b818110156104f8578281556001016104e5565b505050505050565b81516001600160401b03811115610519576105196102b8565b61052d816105278454610476565b846104b0565b602080601f831160018114610562576000841561054a5750858301515b600019600386901b1c1916600185901b1785556104f8565b600085815260208120601f198616915b8281101561059157888601518255948401946001909101908401610572565b50858210156105af5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176105ec576105ec6105bf565b92915050565b60006001600160a01b038381168061061a57634e487b7160e01b600052601260045260246000fd5b92169190910692915050565b808201808211156105ec576105ec6105bf565b634e487b7160e01b600052603260045260246000fd5b60805160a05160c051611a4961068c600039600081816102de0152610a520152600081816103250152610a2701526000610a7c0152611a496000f3fe60806040526004361061018e5760003560e01c8063571ff20d116100d6578063a0712d681161007f578063b623890111610059578063b623890114610585578063d9f50046146105a5578063dd62ed3e146105c55761019d565b8063a0712d6814610532578063a457c2d714610545578063a9059cbb146105655761019d565b80637db802ca116100b05780637db802ca1461050057806395d89b41146105085780639d1b464a1461051d5761019d565b8063571ff20d1461048a57806370a08231146104aa57806378a3727b146104e05761019d565b806318160ddd11610138578063313ce56711610112578063313ce5671461042e578063395093511461044a57806342966c681461046a5761019d565b806318160ddd146103d957806323b872dd146103ee57806327de8f271461040e5761019d565b8063095ea7b311610169578063095ea7b3146103695780630dc561ba1461039957806313467092146103b95761019d565b806218b1d3146102cc578063041151871461031357806306fdde03146103475761019d565b3661019d5761019b61060b565b005b60646101a860025490565b6101b390604d611509565b6101bd9190611520565b33600090815260208190526040902054116101eb5760405163742b13ff60e11b815260040160405180910390fd5b635e4abfed60e11b6101fe366000611542565b6001600160e01b0319160361019b57601836101561022f57604051638129bbcd60e01b815260040160405180910390fd5b60008061023f3660048184611572565b81019061024c91906115f8565b915091506000826001600160a01b03168260405161026a91906116c4565b600060405180830381855af49150503d80600081146102a5576040519150601f19603f3d011682016040523d82523d6000602084013e6102aa565b606091505b505090508061019b576040516318cecad560e01b815260040160405180910390fd5b3480156102d857600080fd5b506103007f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561031f57600080fd5b506103007f000000000000000000000000000000000000000000000000000000000000000081565b34801561035357600080fd5b5061035c61062d565b60405161030a919061170c565b34801561037557600080fd5b50610389610384366004611726565b6106bf565b604051901515815260200161030a565b3480156103a557600080fd5b506103006103b4366004611752565b6106d9565b3480156103c557600080fd5b506103006103d4366004611752565b61070a565b3480156103e557600080fd5b50600254610300565b3480156103fa57600080fd5b5061038961040936600461176b565b610743565b34801561041a57600080fd5b50610300610429366004611752565b610767565b34801561043a57600080fd5b506040516012815260200161030a565b34801561045657600080fd5b50610389610465366004611726565b61077c565b34801561047657600080fd5b50610300610485366004611752565b6107bb565b34801561049657600080fd5b506103006104a53660046117ac565b610841565b3480156104b657600080fd5b506103006104c53660046117dc565b6001600160a01b031660009081526020819052604090205490565b3480156104ec57600080fd5b5061019b6104fb3660046117f9565b6108d3565b61030061060b565b34801561051457600080fd5b5061035c610a11565b34801561052957600080fd5b50610300610a20565b61019b610540366004611752565b610aa5565b34801561055157600080fd5b50610389610560366004611726565b610adb565b34801561057157600080fd5b50610389610580366004611726565b610b8a565b34801561059157600080fd5b506103006105a036600461182e565b610b98565b3480156105b157600080fd5b5061019b6105c036600461176b565b610dfb565b3480156105d157600080fd5b506103006105e03660046118ec565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6000610615610a20565b61061f9034611520565b905061062a81610aa5565b90565b60606003805461063c9061191a565b80601f01602080910402602001604051908101604052809291908181526020018280546106689061191a565b80156106b55780601f1061068a576101008083540402835291602001916106b5565b820191906000526020600020905b81548152906001019060200180831161069857829003601f168201915b5050505050905090565b6000336106cd818585610f80565b60019150505b92915050565b6000806106e560025490565b1115610705576002546106f84784611509565b6107029190611520565b90505b919050565b3360009081526020819052604081205482111561073a5760405163064c392760e21b815260040160405180910390fd5b610702826107bb565b6000336107518582856110a5565b61075c858585611137565b506001949350505050565b600081610772610a20565b6107029190611509565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091906106cd90829086906107b690879061194e565b610f80565b60006107c6826106d9565b90506107d2338361130a565b604051600090339083908381818185875af1925050503d8060008114610814576040519150601f19603f3d011682016040523d82523d6000602084013e610819565b606091505b505090508061083b57604051630958b5bb60e41b815260040160405180910390fd5b50919050565b600061084c836106d9565b9050610858338461130a565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146108a5576040519150601f19603f3d011682016040523d82523d6000602084013e6108aa565b606091505b50509050806108cc57604051630958b5bb60e41b815260040160405180910390fd5b5092915050565b6001600160a01b0383166108fa5760405163d92e233d60e01b815260040160405180910390fd5b610904338361130a565b604080513360248201526001600160a01b0385166044820152606480820185905282518083039091018152608490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16636cfa802360e11b1790529051637056f41f60e01b81526023602160991b0190637056f41f9061099290859030908690600401611961565b600060405180830381600087803b1580156109ac57600080fd5b505af11580156109c0573d6000803e3d6000fd5b505060408051868152602081018690526001600160a01b03881693503392507ffcea3600a13c757f2758710b089cc9752781c35d2a9d6804370ed18cd82f0bb691015b60405180910390a350505050565b60606004805461063c9061191a565b6000610a4c7f000000000000000000000000000000000000000000000000000000000000000042611992565b610a76907f0000000000000000000000000000000000000000000000000000000000000000611509565b610aa0907f000000000000000000000000000000000000000000000000000000000000000061194e565b905090565b610aae81610767565b341015610ace5760405163dd8e4af760e01b815260040160405180910390fd5b610ad83382611434565b50565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919083811015610b7d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61075c8286868403610f80565b6000336106cd818585611137565b33600090815260208190526040812054831115610bc85760405163064c392760e21b815260040160405180910390fd5b82610bd260025490565b610bdc9190611520565b9050610be8338461130a565b60055460ff1615610c0c5760405163769dd35360e11b815260040160405180910390fd5b6005805460ff191660019081179091556000905b8351821015610d79576000848381518110610c3d57610c3d6119a5565b60209081029190910101516040516370a0823160e01b81523060048201529091506001600160a01b038216906370a0823190602401602060405180830381865afa158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb391906119bb565b95508115610d4f57818015610d4c57506001600160a01b03811663a9059cbb33610cdd878a611520565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610d28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4c91906119d4565b91505b81610d6d576040516301fd421760e71b815260040160405180910390fd5b82600101925050610c20565b33610d848447611520565b604051600081818185875af1925050503d8060008114610dc0576040519150601f19603f3d011682016040523d82523d6000602084013e610dc5565b606091505b50508091505080610de9576040516365a1711b60e01b815260040160405180910390fd5b50506005805460ff1916905592915050565b336023602160991b0114610e21576040516265d51560e41b815260040160405180910390fd5b306001600160a01b03166023602160991b016001600160a01b03166338ffde186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9491906119f6565b6001600160a01b031614610ebb57604051635e11715560e11b815260040160405180910390fd5b60006023602160991b016001600160a01b031663247944626040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2691906119bb565b9050610f328383611434565b826001600160a01b0316846001600160a01b03167fc75e22a0b57fb7740dbfc0caa5c6b7a82a2139964e7f1b7be7ac4e8be0f719ba8484604051610a03929190918252602082015260400190565b6001600160a01b038316610fe25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610b74565b6001600160a01b0382166110435760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610b74565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b03838116600090815260016020908152604080832093861683529290522054600019811461113157818110156111245760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610b74565b6111318484848403610f80565b50505050565b6001600160a01b0383166111b35760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610b74565b6001600160a01b0382166112155760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610b74565b6001600160a01b038316600090815260208190526040902054818110156112a45760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610b74565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3611131565b6001600160a01b03821661136a5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610b74565b6001600160a01b038216600090815260208190526040902054818110156113de5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610b74565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101611098565b6001600160a01b03821661148a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610b74565b806002600082825461149c919061194e565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176106d3576106d36114f3565b60008261153d57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160e01b0319813581811691600485101561156a5780818660040360031b1b83161692505b505092915050565b6000808585111561158257600080fd5b8386111561158f57600080fd5b5050820193919092039150565b6001600160a01b0381168114610ad857600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156115f0576115f06115b1565b604052919050565b6000806040838503121561160b57600080fd5b82356116168161159c565b915060208381013567ffffffffffffffff8082111561163457600080fd5b818601915086601f83011261164857600080fd5b81358181111561165a5761165a6115b1565b61166c601f8201601f191685016115c7565b9150808252878482850101111561168257600080fd5b80848401858401376000848284010152508093505050509250929050565b60005b838110156116bb5781810151838201526020016116a3565b50506000910152565b600082516116d68184602087016116a0565b9190910192915050565b600081518084526116f88160208601602086016116a0565b601f01601f19169290920160200192915050565b60208152600061171f60208301846116e0565b9392505050565b6000806040838503121561173957600080fd5b82356117448161159c565b946020939093013593505050565b60006020828403121561176457600080fd5b5035919050565b60008060006060848603121561178057600080fd5b833561178b8161159c565b9250602084013561179b8161159c565b929592945050506040919091013590565b600080604083850312156117bf57600080fd5b8235915060208301356117d18161159c565b809150509250929050565b6000602082840312156117ee57600080fd5b813561171f8161159c565b60008060006060848603121561180e57600080fd5b83356118198161159c565b95602085013595506040909401359392505050565b6000806040838503121561184157600080fd5b8235915060208084013567ffffffffffffffff8082111561186157600080fd5b818601915086601f83011261187557600080fd5b813581811115611887576118876115b1565b8060051b91506118988483016115c7565b81815291830184019184810190898411156118b257600080fd5b938501935b838510156118dc57843592506118cc8361159c565b82825293850193908501906118b7565b8096505050505050509250929050565b600080604083850312156118ff57600080fd5b823561190a8161159c565b915060208301356117d18161159c565b600181811c9082168061192e57607f821691505b60208210810361083b57634e487b7160e01b600052602260045260246000fd5b808201808211156106d3576106d36114f3565b8381526001600160a01b038316602082015260606040820152600061198960608301846116e0565b95945050505050565b818103818111156106d3576106d36114f3565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156119cd57600080fd5b5051919050565b6000602082840312156119e657600080fd5b8151801515811461171f57600080fd5b600060208284031215611a0857600080fd5b815161171f8161159c56fea26469706673582212202ef304b025ba03afe21c70eacbd98224525b0eba6d5a322131a2c5b4dee46b9f64736f6c6343000819003300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c9a9c487bb6f53ba8abe8471d39358c875b388c500000000000000000000000032e3c7fd24e175701a35c224f2238d18439c7dbc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000000000000000000000009195731e2ce35eb000000
Deployed ByteCode
0x60806040526004361061018e5760003560e01c8063571ff20d116100d6578063a0712d681161007f578063b623890111610059578063b623890114610585578063d9f50046146105a5578063dd62ed3e146105c55761019d565b8063a0712d6814610532578063a457c2d714610545578063a9059cbb146105655761019d565b80637db802ca116100b05780637db802ca1461050057806395d89b41146105085780639d1b464a1461051d5761019d565b8063571ff20d1461048a57806370a08231146104aa57806378a3727b146104e05761019d565b806318160ddd11610138578063313ce56711610112578063313ce5671461042e578063395093511461044a57806342966c681461046a5761019d565b806318160ddd146103d957806323b872dd146103ee57806327de8f271461040e5761019d565b8063095ea7b311610169578063095ea7b3146103695780630dc561ba1461039957806313467092146103b95761019d565b806218b1d3146102cc578063041151871461031357806306fdde03146103475761019d565b3661019d5761019b61060b565b005b60646101a860025490565b6101b390604d611509565b6101bd9190611520565b33600090815260208190526040902054116101eb5760405163742b13ff60e11b815260040160405180910390fd5b635e4abfed60e11b6101fe366000611542565b6001600160e01b0319160361019b57601836101561022f57604051638129bbcd60e01b815260040160405180910390fd5b60008061023f3660048184611572565b81019061024c91906115f8565b915091506000826001600160a01b03168260405161026a91906116c4565b600060405180830381855af49150503d80600081146102a5576040519150601f19603f3d011682016040523d82523d6000602084013e6102aa565b606091505b505090508061019b576040516318cecad560e01b815260040160405180910390fd5b3480156102d857600080fd5b506103007f000000000000000000000000000000000000000000000000000000000000000181565b6040519081526020015b60405180910390f35b34801561031f57600080fd5b506103007f000000000000000000000000000000000000000000000000000000006723a0d481565b34801561035357600080fd5b5061035c61062d565b60405161030a919061170c565b34801561037557600080fd5b50610389610384366004611726565b6106bf565b604051901515815260200161030a565b3480156103a557600080fd5b506103006103b4366004611752565b6106d9565b3480156103c557600080fd5b506103006103d4366004611752565b61070a565b3480156103e557600080fd5b50600254610300565b3480156103fa57600080fd5b5061038961040936600461176b565b610743565b34801561041a57600080fd5b50610300610429366004611752565b610767565b34801561043a57600080fd5b506040516012815260200161030a565b34801561045657600080fd5b50610389610465366004611726565b61077c565b34801561047657600080fd5b50610300610485366004611752565b6107bb565b34801561049657600080fd5b506103006104a53660046117ac565b610841565b3480156104b657600080fd5b506103006104c53660046117dc565b6001600160a01b031660009081526020819052604090205490565b3480156104ec57600080fd5b5061019b6104fb3660046117f9565b6108d3565b61030061060b565b34801561051457600080fd5b5061035c610a11565b34801561052957600080fd5b50610300610a20565b61019b610540366004611752565b610aa5565b34801561055157600080fd5b50610389610560366004611726565b610adb565b34801561057157600080fd5b50610389610580366004611726565b610b8a565b34801561059157600080fd5b506103006105a036600461182e565b610b98565b3480156105b157600080fd5b5061019b6105c036600461176b565b610dfb565b3480156105d157600080fd5b506103006105e03660046118ec565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6000610615610a20565b61061f9034611520565b905061062a81610aa5565b90565b60606003805461063c9061191a565b80601f01602080910402602001604051908101604052809291908181526020018280546106689061191a565b80156106b55780601f1061068a576101008083540402835291602001916106b5565b820191906000526020600020905b81548152906001019060200180831161069857829003601f168201915b5050505050905090565b6000336106cd818585610f80565b60019150505b92915050565b6000806106e560025490565b1115610705576002546106f84784611509565b6107029190611520565b90505b919050565b3360009081526020819052604081205482111561073a5760405163064c392760e21b815260040160405180910390fd5b610702826107bb565b6000336107518582856110a5565b61075c858585611137565b506001949350505050565b600081610772610a20565b6107029190611509565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091906106cd90829086906107b690879061194e565b610f80565b60006107c6826106d9565b90506107d2338361130a565b604051600090339083908381818185875af1925050503d8060008114610814576040519150601f19603f3d011682016040523d82523d6000602084013e610819565b606091505b505090508061083b57604051630958b5bb60e41b815260040160405180910390fd5b50919050565b600061084c836106d9565b9050610858338461130a565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146108a5576040519150601f19603f3d011682016040523d82523d6000602084013e6108aa565b606091505b50509050806108cc57604051630958b5bb60e41b815260040160405180910390fd5b5092915050565b6001600160a01b0383166108fa5760405163d92e233d60e01b815260040160405180910390fd5b610904338361130a565b604080513360248201526001600160a01b0385166044820152606480820185905282518083039091018152608490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16636cfa802360e11b1790529051637056f41f60e01b81526023602160991b0190637056f41f9061099290859030908690600401611961565b600060405180830381600087803b1580156109ac57600080fd5b505af11580156109c0573d6000803e3d6000fd5b505060408051868152602081018690526001600160a01b03881693503392507ffcea3600a13c757f2758710b089cc9752781c35d2a9d6804370ed18cd82f0bb691015b60405180910390a350505050565b60606004805461063c9061191a565b6000610a4c7f000000000000000000000000000000000000000000000000000000006723a0d442611992565b610a76907f0000000000000000000000000000000000000000000000000000000000000001611509565b610aa0907f000000000000000000000000000000000000000000000000000000003b9aca0061194e565b905090565b610aae81610767565b341015610ace5760405163dd8e4af760e01b815260040160405180910390fd5b610ad83382611434565b50565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919083811015610b7d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61075c8286868403610f80565b6000336106cd818585611137565b33600090815260208190526040812054831115610bc85760405163064c392760e21b815260040160405180910390fd5b82610bd260025490565b610bdc9190611520565b9050610be8338461130a565b60055460ff1615610c0c5760405163769dd35360e11b815260040160405180910390fd5b6005805460ff191660019081179091556000905b8351821015610d79576000848381518110610c3d57610c3d6119a5565b60209081029190910101516040516370a0823160e01b81523060048201529091506001600160a01b038216906370a0823190602401602060405180830381865afa158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb391906119bb565b95508115610d4f57818015610d4c57506001600160a01b03811663a9059cbb33610cdd878a611520565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610d28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4c91906119d4565b91505b81610d6d576040516301fd421760e71b815260040160405180910390fd5b82600101925050610c20565b33610d848447611520565b604051600081818185875af1925050503d8060008114610dc0576040519150601f19603f3d011682016040523d82523d6000602084013e610dc5565b606091505b50508091505080610de9576040516365a1711b60e01b815260040160405180910390fd5b50506005805460ff1916905592915050565b336023602160991b0114610e21576040516265d51560e41b815260040160405180910390fd5b306001600160a01b03166023602160991b016001600160a01b03166338ffde186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9491906119f6565b6001600160a01b031614610ebb57604051635e11715560e11b815260040160405180910390fd5b60006023602160991b016001600160a01b031663247944626040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2691906119bb565b9050610f328383611434565b826001600160a01b0316846001600160a01b03167fc75e22a0b57fb7740dbfc0caa5c6b7a82a2139964e7f1b7be7ac4e8be0f719ba8484604051610a03929190918252602082015260400190565b6001600160a01b038316610fe25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610b74565b6001600160a01b0382166110435760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610b74565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b03838116600090815260016020908152604080832093861683529290522054600019811461113157818110156111245760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610b74565b6111318484848403610f80565b50505050565b6001600160a01b0383166111b35760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610b74565b6001600160a01b0382166112155760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610b74565b6001600160a01b038316600090815260208190526040902054818110156112a45760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610b74565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3611131565b6001600160a01b03821661136a5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610b74565b6001600160a01b038216600090815260208190526040902054818110156113de5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610b74565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101611098565b6001600160a01b03821661148a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610b74565b806002600082825461149c919061194e565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176106d3576106d36114f3565b60008261153d57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160e01b0319813581811691600485101561156a5780818660040360031b1b83161692505b505092915050565b6000808585111561158257600080fd5b8386111561158f57600080fd5b5050820193919092039150565b6001600160a01b0381168114610ad857600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156115f0576115f06115b1565b604052919050565b6000806040838503121561160b57600080fd5b82356116168161159c565b915060208381013567ffffffffffffffff8082111561163457600080fd5b818601915086601f83011261164857600080fd5b81358181111561165a5761165a6115b1565b61166c601f8201601f191685016115c7565b9150808252878482850101111561168257600080fd5b80848401858401376000848284010152508093505050509250929050565b60005b838110156116bb5781810151838201526020016116a3565b50506000910152565b600082516116d68184602087016116a0565b9190910192915050565b600081518084526116f88160208601602086016116a0565b601f01601f19169290920160200192915050565b60208152600061171f60208301846116e0565b9392505050565b6000806040838503121561173957600080fd5b82356117448161159c565b946020939093013593505050565b60006020828403121561176457600080fd5b5035919050565b60008060006060848603121561178057600080fd5b833561178b8161159c565b9250602084013561179b8161159c565b929592945050506040919091013590565b600080604083850312156117bf57600080fd5b8235915060208301356117d18161159c565b809150509250929050565b6000602082840312156117ee57600080fd5b813561171f8161159c565b60008060006060848603121561180e57600080fd5b83356118198161159c565b95602085013595506040909401359392505050565b6000806040838503121561184157600080fd5b8235915060208084013567ffffffffffffffff8082111561186157600080fd5b818601915086601f83011261187557600080fd5b813581811115611887576118876115b1565b8060051b91506118988483016115c7565b81815291830184019184810190898411156118b257600080fd5b938501935b838510156118dc57843592506118cc8361159c565b82825293850193908501906118b7565b8096505050505050509250929050565b600080604083850312156118ff57600080fd5b823561190a8161159c565b915060208301356117d18161159c565b600181811c9082168061192e57607f821691505b60208210810361083b57634e487b7160e01b600052602260045260246000fd5b808201808211156106d3576106d36114f3565b8381526001600160a01b038316602082015260606040820152600061198960608301846116e0565b95945050505050565b818103818111156106d3576106d36114f3565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156119cd57600080fd5b5051919050565b6000602082840312156119e657600080fd5b8151801515811461171f57600080fd5b600060208284031215611a0857600080fd5b815161171f8161159c56fea26469706673582212202ef304b025ba03afe21c70eacbd98224525b0eba6d5a322131a2c5b4dee46b9f64736f6c63430008190033