Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Token
- Optimization enabled
- true
- Compiler version
- v0.8.18+commit.87f61d96
- Optimization runs
- 20000
- EVM Version
- default
- Verified at
- 2024-02-07T08:53:09.610397Z
contracts/token/Token.sol
// SPDX-License-Identifier: GPL-3.0-or-later // Based on ERC20 implementation of @openzeppelin/contracts (v4.5.0): // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/token/ERC20/ERC20.sol pragma solidity ^0.8.0; import {SafeMath} from "@openzeppelin/contracts/utils/math/SafeMath.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {MultiCurrency} from "./MultiCurrency.sol"; import {IToken} from "./IToken.sol"; /// @title MultiCurrency Predeploy Contract /// @author Acala Developers /// @notice You can use this predeploy contract to call currencies pallet /// @dev This contracts will interact with currencies pallet contract Token is IToken { using SafeMath for uint256; mapping(address => mapping(address => uint256)) private _allowances; /// @notice Get the name of the token. /// @return Returns the name of the token. function name() public view returns (string memory) { return MultiCurrency.name(); } /// @notice Get the symbol of the token, usually a shorter version of the name. /// @return Returns the symbol of the token. function symbol() public view returns (string memory) { return MultiCurrency.symbol(); } /// @notice Get the number of decimals used to get its user representation. /// @return Returns the number of decimals. function decimals() public view returns (uint8) { return MultiCurrency.decimals(); } /// @notice Get the amount of tokens in existence. /// @return Returns amount of tokens in existence. function totalSupply() public view override returns (uint256) { return MultiCurrency.totalSupply(); } /// @notice Get the amount of tokens owned by `account`. /// @param account The specified user. /// @return Returns the amount of tokens owned by `account`. function balanceOf(address account) public view override returns (uint256) { return MultiCurrency.balanceOf(account); } /// @notice Moves `amount` tokens from the caller's account to `to`. /// @dev It'll emit an {Transfer} event. The caller must have a balance of at least `amount`. /// @param to The dest address, it cannot be the zero address. /// @param amount The transfer amount. /// @return Returns a boolean value indicating whether the operation succeeded. function transfer( address to, uint256 amount ) public override returns (bool) { address owner = msg.sender; _transfer(owner, to, amount); return true; } /// @notice Get the remaining number of tokens that `spender` will be allowed to spend. /// @param owner The owner address. /// @param spender The spender address. /// @return Returns the remaining number of tokens. /// The `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. function allowance( address owner, address spender ) public view override returns (uint256) { return _allowances[owner][spender]; } /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. /// @dev It'll emit an {Approval} event. /// If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. /// This is semantically equivalent to an infinite approval. /// @param spender Approve the spender. /// @param amount The approve amount. /// @return Returns a boolean value indicating whether the operation succeeded. function approve( address spender, uint256 amount ) public override returns (bool) { address owner = msg.sender; _approve(owner, spender, amount); return true; } /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. /// `amount` is then deducted from the caller's allowance. /// @dev It'll emit an {Transfer} event. /// @param from Transfer amount from the address. /// The caller must have allowance for ``from``'s tokens of at least `amount`. It cannot be the zero address. /// @param to Transfer amount to the address. It cannot be the zero address. /// @param amount The transfer amount. /// @return Returns a boolean value indicating whether the operation succeeded. function transferFrom( address from, address to, uint256 amount ) public override returns (bool) { address spender = msg.sender; _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. /// @param spender It cannot be the zero address. /// @param addedValue The added value. /// @return Returns a boolean value indicating whether the operation succeeded. function increaseAllowance( address spender, uint256 addedValue ) public returns (bool) { address owner = msg.sender; _approve(owner, spender, _allowances[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. /// @param spender must have allowance for the caller of at least `subtractedValue`. It cannot be the zero address. /// @param subtractedValue The subtracted value. /// @return Returns a boolean value indicating whether the operation succeeded. function decreaseAllowance( address spender, uint256 subtractedValue ) public returns (bool) { address owner = msg.sender; uint256 currentAllowance = _allowances[owner][spender]; require( currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero" ); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /// @inheritdoc IToken function transferToAccountId32( bytes32 dest, uint256 amount ) public override returns (bool) { address from = msg.sender; require( dest != 0x0000000000000000000000000000000000000000000000000000000000000000, "ERC20: transfer to the zero AccountId32" ); MultiCurrency.transferToAccountId(from, dest, amount); emit TransferToAccountId32(from, dest, amount); return true; } /// @dev Moves `amount` of tokens from `sender` to `recipient`. /// 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. /// @param from must have a balance of at least `amount`. It cannot be the zero address. /// @param to It cannot be the zero address. function _transfer(address from, address to, uint256 amount) internal { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); MultiCurrency.transfer(from, to, amount); emit Transfer(from, to, 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. /// @param owner cannot be the zero address. /// @param spender cannot be the zero address. function _approve(address owner, address spender, uint256 amount) internal { 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 Spend `amount` form the allowance of `owner` toward `spender`. /// 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 { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require( currentAllowance >= amount, "ERC20: insufficient allowance" ); unchecked { _approve(owner, spender, currentAllowance - amount); } } } }
@openzeppelin/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); }
@openzeppelin/contracts/utils/math/SafeMath.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
contracts/token/IToken.sol
// SPDX-License-Identifier: GPL-3.0-or-later // inherit on IERC20 interface of @openzeppelin/contracts (v4.5.0): // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/token/ERC20/IERC20.sol pragma solidity ^0.8.0; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /// @title IToken Predeploy Contract Interface /// @author Acala Developers /// @notice You can use this predeploy contract to call currencies pallet /// @dev The interface through which solidity contracts will interact with currencies pallet interface IToken is IERC20 { /// @notice Transfer event to AccountId32 type account. /// @param sender The sender of the transaction. /// @param dest The dest AccountId32 type account. /// @param amount The transfer amount. /// @dev This is Transfer event which transfer AccountId32 type account. event TransferToAccountId32( address indexed sender, bytes32 indexed dest, uint256 amount ); /// @notice Moves `amount` tokens from the caller's account to `dest`, which is AccountId32 type account. /// @dev It'll emit an {TransferToAccountId32} event. The caller must have a balance of at least `amount`. /// @param dest The dest AccountId32 type account, it cannot be the zero AccountId32. /// @param amount The transfer amount. /// @return Returns a boolean value indicating whether the operation succeeded. function transferToAccountId32( bytes32 dest, uint256 amount ) external returns (bool); }
contracts/token/MultiCurrency.sol
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; /// @title MultiCurrency Predeploy Contract Library /// @author Acala Developers /// @notice You can use this predeploy contract to call currencies pallet /// @dev This contracts will interact with currencies pallet library MultiCurrency { /// @dev The MultiCurrency precompile address. address private constant PRECOMPILE = address(0x0000000000000000000000000000000000000400); function name() internal view returns (string memory) { (bool success, bytes memory returnData) = PRECOMPILE.staticcall( abi.encodeWithSignature("name()") ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } return abi.decode(returnData, (string)); } function symbol() internal view returns (string memory) { (bool success, bytes memory returnData) = PRECOMPILE.staticcall( abi.encodeWithSignature("symbol()") ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } return abi.decode(returnData, (string)); } function decimals() internal view returns (uint8) { (bool success, bytes memory returnData) = PRECOMPILE.staticcall( abi.encodeWithSignature("decimals()") ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } return abi.decode(returnData, (uint8)); } function totalSupply() internal view returns (uint256) { (bool success, bytes memory returnData) = PRECOMPILE.staticcall( abi.encodeWithSignature("totalSupply()") ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } return abi.decode(returnData, (uint256)); } function balanceOf(address account) internal view returns (uint256) { (bool success, bytes memory returnData) = PRECOMPILE.staticcall( abi.encodeWithSignature("balanceOf(address)", account) ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } return abi.decode(returnData, (uint256)); } function transfer( address sender, address recipient, uint256 amount ) internal { (bool success, bytes memory returnData) = PRECOMPILE.call( abi.encodeWithSignature( "transfer(address,address,uint256)", sender, recipient, amount ) ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } } function transferToAccountId( address sender, bytes32 recipient, uint256 amount ) internal { (bool success, bytes memory returnData) = PRECOMPILE.call( abi.encodeWithSignature( "transferToAccountId(address,bytes32,uint256)", sender, recipient, amount ) ); assembly { if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) } } } }
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":20000,"enabled":true},"libraries":{}}
Contract ABI
[{"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":"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":"event","name":"TransferToAccountId32","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"bytes32","name":"dest","internalType":"bytes32","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"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":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"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":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"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":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferToAccountId32","inputs":[{"type":"bytes32","name":"dest","internalType":"bytes32"},{"type":"uint256","name":"amount","internalType":"uint256"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b506111f1806100206000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806370a0823111610081578063a457c2d71161005b578063a457c2d71461019e578063a9059cbb146101b1578063dd62ed3e146101c457600080fd5b806370a0823114610170578063871069c01461018357806395d89b411461019657600080fd5b806323b872dd116100b257806323b872dd14610130578063313ce56714610143578063395093511461015d57600080fd5b806306fdde03146100d9578063095ea7b3146100f757806318160ddd1461011a575b600080fd5b6100e1610208565b6040516100ee9190610ed8565b60405180910390f35b61010a610105366004610f52565b610217565b60405190151581526020016100ee565b610122610231565b6040519081526020016100ee565b61010a61013e366004610f7c565b61023b565b61014b61025f565b60405160ff90911681526020016100ee565b61010a61016b366004610f52565b610269565b61012261017e366004610fb8565b6102b3565b61010a610191366004610fda565b6102be565b6100e16103bb565b61010a6101ac366004610f52565b6103c5565b61010a6101bf366004610f52565b610494565b6101226101d2366004610ffc565b73ffffffffffffffffffffffffffffffffffffffff91821660009081526020818152604080832093909416825291909152205490565b60606102126104a2565b905090565b60003361022581858561057d565b60019150505b92915050565b600061021261072f565b600033610249858285610802565b6102548585856108d7565b506001949350505050565b6000610212610a87565b3360008181526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061022590829086906102ae90879061102f565b61057d565b600061022b82610b5a565b600033838203610355576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f45524332303a207472616e7366657220746f20746865207a65726f204163636f60448201527f756e74496433320000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610360818585610c76565b838173ffffffffffffffffffffffffffffffffffffffff167f1d17b5770b13229fb9a0fbb368edadb0cd26837679bf04920d26031ad8fd6bdc856040516103a991815260200190565b60405180910390a35060019392505050565b6060610212610d8b565b3360008181526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161034c565b610254828686840361057d565b6000336102258185856108d7565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde030000000000000000000000000000000000000000000000000000000017905290516060916000918291610400916105109190611069565b600060405180830381855afa9150503d806000811461054b576040519150601f19603f3d011682016040523d82523d6000602084013e610550565b606091505b50909250905081610562573d60208201fd5b8080602001905181019061057691906110b4565b9250505090565b73ffffffffffffffffffffffffffffffffffffffff831661061f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161034c565b73ffffffffffffffffffffffffffffffffffffffff82166106c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161034c565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152602081815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f18160ddd000000000000000000000000000000000000000000000000000000001790529051600091829182916104009161079c9190611069565b600060405180830381855afa9150503d80600081146107d7576040519150601f19603f3d011682016040523d82523d6000602084013e6107dc565b606091505b509092509050816107ee573d60208201fd5b80806020019051810190610576919061117f565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260208181526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146108d157818110156108c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161034c565b6108d1848484840361057d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff831661097a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161034c565b73ffffffffffffffffffffffffffffffffffffffff8216610a1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161034c565b610a28838383610df9565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161072291815260200190565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290516000918291829161040091610af49190611069565b600060405180830381855afa9150503d8060008114610b2f576040519150601f19603f3d011682016040523d82523d6000602084013e610b34565b606091505b50909250905081610b46573d60208201fd5b808060200190518101906105769190611198565b60405173ffffffffffffffffffffffffffffffffffffffff821660248201526000908190819061040090604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905251610c089190611069565b600060405180830381855afa9150503d8060008114610c43576040519150601f19603f3d011682016040523d82523d6000602084013e610c48565b606091505b50909250905081610c5a573d60208201fd5b80806020019051810190610c6e919061117f565b949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff841660248201526044810183905260648101829052600090819061040090608401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f895904980000000000000000000000000000000000000000000000000000000017905251610d309190611069565b6000604051808303816000865af19150503d8060008114610d6d576040519150601f19603f3d011682016040523d82523d6000602084013e610d72565b606091505b50909250905081610d84573d60208201fd5b5050505050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b410000000000000000000000000000000000000000000000000000000017905290516060916000918291610400916105109190611069565b60405173ffffffffffffffffffffffffffffffffffffffff84811660248301528316604482015260648101829052600090819061040090608401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fbeabacc80000000000000000000000000000000000000000000000000000000017905251610d309190611069565b60005b83811015610ecf578181015183820152602001610eb7565b50506000910152565b6020815260008251806020840152610ef7816040850160208701610eb4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610f4d57600080fd5b919050565b60008060408385031215610f6557600080fd5b610f6e83610f29565b946020939093013593505050565b600080600060608486031215610f9157600080fd5b610f9a84610f29565b9250610fa860208501610f29565b9150604084013590509250925092565b600060208284031215610fca57600080fd5b610fd382610f29565b9392505050565b60008060408385031215610fed57600080fd5b50508035926020909101359150565b6000806040838503121561100f57600080fd5b61101883610f29565b915061102660208401610f29565b90509250929050565b8082018082111561022b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000825161107b818460208701610eb4565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156110c657600080fd5b815167ffffffffffffffff808211156110de57600080fd5b818401915084601f8301126110f257600080fd5b81518181111561110457611104611085565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561114a5761114a611085565b8160405282815287602084870101111561116357600080fd5b611174836020830160208801610eb4565b979650505050505050565b60006020828403121561119157600080fd5b5051919050565b6000602082840312156111aa57600080fd5b815160ff81168114610fd357600080fdfea2646970667358221220054e18bc0b3f0a07464c0663a4015c3aa60d5e66cf648752fbf056e6eeefc5e864736f6c63430008120033
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806370a0823111610081578063a457c2d71161005b578063a457c2d71461019e578063a9059cbb146101b1578063dd62ed3e146101c457600080fd5b806370a0823114610170578063871069c01461018357806395d89b411461019657600080fd5b806323b872dd116100b257806323b872dd14610130578063313ce56714610143578063395093511461015d57600080fd5b806306fdde03146100d9578063095ea7b3146100f757806318160ddd1461011a575b600080fd5b6100e1610208565b6040516100ee9190610ed8565b60405180910390f35b61010a610105366004610f52565b610217565b60405190151581526020016100ee565b610122610231565b6040519081526020016100ee565b61010a61013e366004610f7c565b61023b565b61014b61025f565b60405160ff90911681526020016100ee565b61010a61016b366004610f52565b610269565b61012261017e366004610fb8565b6102b3565b61010a610191366004610fda565b6102be565b6100e16103bb565b61010a6101ac366004610f52565b6103c5565b61010a6101bf366004610f52565b610494565b6101226101d2366004610ffc565b73ffffffffffffffffffffffffffffffffffffffff91821660009081526020818152604080832093909416825291909152205490565b60606102126104a2565b905090565b60003361022581858561057d565b60019150505b92915050565b600061021261072f565b600033610249858285610802565b6102548585856108d7565b506001949350505050565b6000610212610a87565b3360008181526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061022590829086906102ae90879061102f565b61057d565b600061022b82610b5a565b600033838203610355576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f45524332303a207472616e7366657220746f20746865207a65726f204163636f60448201527f756e74496433320000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610360818585610c76565b838173ffffffffffffffffffffffffffffffffffffffff167f1d17b5770b13229fb9a0fbb368edadb0cd26837679bf04920d26031ad8fd6bdc856040516103a991815260200190565b60405180910390a35060019392505050565b6060610212610d8b565b3360008181526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161034c565b610254828686840361057d565b6000336102258185856108d7565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde030000000000000000000000000000000000000000000000000000000017905290516060916000918291610400916105109190611069565b600060405180830381855afa9150503d806000811461054b576040519150601f19603f3d011682016040523d82523d6000602084013e610550565b606091505b50909250905081610562573d60208201fd5b8080602001905181019061057691906110b4565b9250505090565b73ffffffffffffffffffffffffffffffffffffffff831661061f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161034c565b73ffffffffffffffffffffffffffffffffffffffff82166106c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161034c565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152602081815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f18160ddd000000000000000000000000000000000000000000000000000000001790529051600091829182916104009161079c9190611069565b600060405180830381855afa9150503d80600081146107d7576040519150601f19603f3d011682016040523d82523d6000602084013e6107dc565b606091505b509092509050816107ee573d60208201fd5b80806020019051810190610576919061117f565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260208181526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146108d157818110156108c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161034c565b6108d1848484840361057d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff831661097a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161034c565b73ffffffffffffffffffffffffffffffffffffffff8216610a1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161034c565b610a28838383610df9565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161072291815260200190565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290516000918291829161040091610af49190611069565b600060405180830381855afa9150503d8060008114610b2f576040519150601f19603f3d011682016040523d82523d6000602084013e610b34565b606091505b50909250905081610b46573d60208201fd5b808060200190518101906105769190611198565b60405173ffffffffffffffffffffffffffffffffffffffff821660248201526000908190819061040090604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905251610c089190611069565b600060405180830381855afa9150503d8060008114610c43576040519150601f19603f3d011682016040523d82523d6000602084013e610c48565b606091505b50909250905081610c5a573d60208201fd5b80806020019051810190610c6e919061117f565b949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff841660248201526044810183905260648101829052600090819061040090608401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f895904980000000000000000000000000000000000000000000000000000000017905251610d309190611069565b6000604051808303816000865af19150503d8060008114610d6d576040519150601f19603f3d011682016040523d82523d6000602084013e610d72565b606091505b50909250905081610d84573d60208201fd5b5050505050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b410000000000000000000000000000000000000000000000000000000017905290516060916000918291610400916105109190611069565b60405173ffffffffffffffffffffffffffffffffffffffff84811660248301528316604482015260648101829052600090819061040090608401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fbeabacc80000000000000000000000000000000000000000000000000000000017905251610d309190611069565b60005b83811015610ecf578181015183820152602001610eb7565b50506000910152565b6020815260008251806020840152610ef7816040850160208701610eb4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610f4d57600080fd5b919050565b60008060408385031215610f6557600080fd5b610f6e83610f29565b946020939093013593505050565b600080600060608486031215610f9157600080fd5b610f9a84610f29565b9250610fa860208501610f29565b9150604084013590509250925092565b600060208284031215610fca57600080fd5b610fd382610f29565b9392505050565b60008060408385031215610fed57600080fd5b50508035926020909101359150565b6000806040838503121561100f57600080fd5b61101883610f29565b915061102660208401610f29565b90509250929050565b8082018082111561022b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000825161107b818460208701610eb4565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156110c657600080fd5b815167ffffffffffffffff808211156110de57600080fd5b818401915084601f8301126110f257600080fd5b81518181111561110457611104611085565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561114a5761114a611085565b8160405282815287602084870101111561116357600080fd5b611174836020830160208801610eb4565b979650505050505050565b60006020828403121561119157600080fd5b5051919050565b6000602082840312156111aa57600080fd5b815160ff81168114610fd357600080fdfea2646970667358221220054e18bc0b3f0a07464c0663a4015c3aa60d5e66cf648752fbf056e6eeefc5e864736f6c63430008120033