Address Contract Partially Verified
Address
0x1dd0Df760eB950083c1925da19fC7ac1356a190B
Balance
0 ETH
Nonce
1
Code Size
3165 bytes
Creator
0x1e61C10F...586d at tx 0x00d7a8d5...812a61
Last Active
Indexed Transactions
1 (10,630,593 → 10,630,593)
Gas Used (indexed)
59,178
Contract Bytecode
3165 bytes
0x608060405234801561001057600080fd5b50600436106101005760003560e01c806370a0823111610097578063d73dd62311610066578063d73dd62314610330578063dd62ed3e1461035c578063e46638e61461038a578063f2f4eb26146103c057610100565b806370a08231146102b25780638da5cb5b146102d857806395d89b41146102fc578063a9059cbb1461030457610100565b806323de6651116100d357806323de665114610212578063313ce567146102485780635687f2b814610250578063661884631461028657610100565b806306fdde0314610105578063095ea7b31461018257806318160ddd146101c257806323b872dd146101dc575b600080fd5b61010d6103c8565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561014757818101518382015260200161012f565b50505050905090810190601f1680156101745780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101ae6004803603604081101561019857600080fd5b506001600160a01b038135169060200135610517565b604080519115158252519081900360200190f35b6101ca6105bf565b60408051918252519081900360200190f35b6101ae600480360360608110156101f257600080fd5b506001600160a01b0381358116916020810135909116906040013561063f565b6101ae6004803603606081101561022857600080fd5b506001600160a01b038135811691602081013590911690604001356106f0565b6101ca61078e565b6101ae6004803603606081101561026657600080fd5b506001600160a01b038135811691602081013590911690604001356107dd565b6101ae6004803603604081101561029c57600080fd5b506001600160a01b03813516906020013561087b565b6101ca600480360360208110156102c857600080fd5b50356001600160a01b03166108f0565b6102e0610989565b604080516001600160a01b039092168252519081900360200190f35b61010d6109d8565b6101ae6004803603604081101561031a57600080fd5b506001600160a01b038135169060200135610a35565b6101ae6004803603604081101561034657600080fd5b506001600160a01b038135169060200135610aaa565b6101ca6004803603604081101561037257600080fd5b506001600160a01b0381358116916020013516610b1f565b6101ca600480360360608110156103a057600080fd5b506001600160a01b03813581169160208101359091169060400135610ba2565b6102e0610c19565b60008054604080517f6c02a93100000000000000000000000000000000000000000000000000000000815290516060936001600160a01b0390931692636c02a9319260048082019391829003018186803b15801561042557600080fd5b505afa158015610439573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561046257600080fd5b810190808051604051939291908464010000000082111561048257600080fd5b90830190602082018581111561049757600080fd5b82516401000000008111828201881017156104b157600080fd5b82525081516020918201929091019080838360005b838110156104de5781810151838201526020016104c6565b50505050905090810190601f16801561050b5780820380516001836020036101000a031916815260200191505b50604052505050905090565b60008054604080517fe1f21c670000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b038681166024830152604482018690529151919092169163e1f21c6791606480830192602092919082900301818787803b15801561058c57600080fd5b505af11580156105a0573d6000803e3d6000fd5b505050506040513d60208110156105b657600080fd5b50519392505050565b60008060009054906101000a90046001600160a01b03166001600160a01b031663f7abab9e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561060e57600080fd5b505afa158015610622573d6000803e3d6000fd5b505050506040513d602081101561063857600080fd5b5051905090565b60008054604080517f15dacbea0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b038781166024830152868116604483015260648201869052915191909216916315dacbea91608480830192602092919082900301818787803b1580156106bc57600080fd5b505af11580156106d0573d6000803e3d6000fd5b505050506040513d60208110156106e657600080fd5b5051949350505050565b600080546001600160a01b03163314610739576040805162461bcd60e51b815260206004808301919091526024820152635052303160e01b604482015290519081900360640190fd5b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a35060019392505050565b60008060009054906101000a90046001600160a01b03166001600160a01b0316633b97e8566040518163ffffffff1660e01b815260040160206040518083038186803b15801561060e57600080fd5b600080546001600160a01b03163314610826576040805162461bcd60e51b815260206004808301919091526024820152635052303160e01b604482015290519081900360640190fd5b826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a35060019392505050565b60008054604080517ff019c2670000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b038681166024830152604482018690529151919092169163f019c26791606480830192602092919082900301818787803b15801561058c57600080fd5b60008054604080517fe42c08f20000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301529151919092169163e42c08f2916024808301926020929190829003018186803b15801561095757600080fd5b505afa15801561096b573d6000803e3d6000fd5b505050506040513d602081101561098157600080fd5b505192915050565b60008060009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561060e57600080fd5b60008054604080517f7b61c32000000000000000000000000000000000000000000000000000000000815290516060936001600160a01b0390931692637b61c3209260048082019391829003018186803b15801561042557600080fd5b60008054604080517fbeabacc80000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b038681166024830152604482018690529151919092169163beabacc891606480830192602092919082900301818787803b15801561058c57600080fd5b60008054604080517fbcdd61210000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b038681166024830152604482018690529151919092169163bcdd612191606480830192602092919082900301818787803b15801561058c57600080fd5b60008054604080517f119c1c230000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015285811660248301529151919092169163119c1c23916044808301926020929190829003018186803b158015610b8e57600080fd5b505afa1580156105a0573d6000803e3d6000fd5b60008054604080517fe46638e60000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301528681166024830152604482018690529151919092169163e46638e691606480830192602092919082900301818787803b1580156106bc57600080fd5b6000546001600160a01b03168156fea265627a7a72315820528a1ff6e1fc8954db9aeaf5ea43e529e11d0ac02bd87e4fbe9808de4e78374c64736f6c634300050c0032
Verified Source Code Partial Match
Compiler: v0.5.12+commit.7709ece9
EVM: petersburg
Optimization: Yes (1000 runs)
TokenProxy.sol 1498 lines
/************************************************************************** * ____ _ * / ___| | | __ _ _ _ ___ _ __ * | | _____ | | / _` || | | | / _ \| '__| * | |___|_____|| |___| (_| || |_| || __/| | * \____| |_____|\__,_| \__, | \___||_| * |___/ * ************************************************************************** * * The MIT License (MIT) * * Copyright (c) 2016-2019 Cyril Lapinte * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ************************************************************************** * * Flatten Contract: TokenProxy * * Git Commit: * https://github.com/c-layer/contracts/tree/43925ba24cc22f42d0ff7711d0e169e8c2a0e09f * **************************************************************************/ // File: contracts/abstract/Storage.sol pragma solidity >=0.5.0 <0.6.0; /** * @title Storage * * @author Cyril Lapinte - <[email protected]> * * Error messages **/ contract Storage { mapping(address => address) public proxyDelegates; address[] public delegates; } // File: contracts/util/governance/Ownable.sol pragma solidity >=0.5.0 <0.6.0; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". * * Error messages * OW01: Only accessible as owner * OW02: New owner must be non null */ contract Ownable { address public owner; event OwnershipRenounced(address indexed previousOwner); event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner, "OW01"); _; } /** * @dev Allows the current owner to relinquish control of the contract. */ function renounceOwnership() public onlyOwner { emit OwnershipRenounced(owner); owner = address(0); } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function transferOwnership(address _newOwner) public onlyOwner { _transferOwnership(_newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function _transferOwnership(address _newOwner) internal { require(_newOwner != address(0), "OW02"); emit OwnershipTransferred(owner, _newOwner); owner = _newOwner; } } // File: contracts/operable/OperableStorage.sol pragma solidity >=0.5.0 <0.6.0; /** * @title OperableStorage * @dev The Operable contract enable the restrictions of operations to a set of operators * * @author Cyril Lapinte - <[email protected]> * * Error messages */ contract OperableStorage is Ownable, Storage { // Hardcoded role granting all - non sysop - privileges bytes32 constant internal ALL_PRIVILEGES = bytes32("AllPrivileges"); address constant internal ALL_PROXIES = address(0x416c6c50726f78696573); // "AllProxies" struct RoleData { mapping(bytes4 => bool) privileges; } struct OperatorData { bytes32 coreRole; mapping(address => bytes32) proxyRoles; } // Mapping address => role // Mapping role => bytes4 => bool mapping (address => OperatorData) internal operators; mapping (bytes32 => RoleData) internal roles; /** * @dev core role * @param _address operator address */ function coreRole(address _address) public view returns (bytes32) { return operators[_address].coreRole; } /** * @dev proxy role * @param _address operator address */ function proxyRole(address _proxy, address _address) public view returns (bytes32) { return operators[_address].proxyRoles[_proxy]; } /** * @dev has role privilege * @dev low level access to role privilege * @dev ignores ALL_PRIVILEGES role */ function rolePrivilege(bytes32 _role, bytes4 _privilege) public view returns (bool) { return roles[_role].privileges[_privilege]; } /** * @dev roleHasPrivilege */ function roleHasPrivilege(bytes32 _role, bytes4 _privilege) public view returns (bool) { return (_role == ALL_PRIVILEGES) || roles[_role].privileges[_privilege]; } /** * @dev hasCorePrivilege * @param _address operator address */ function hasCorePrivilege(address _address, bytes4 _privilege) public view returns (bool) { bytes32 role = operators[_address].coreRole; return (role == ALL_PRIVILEGES) || roles[role].privileges[_privilege]; } /** * @dev hasProxyPrivilege * @dev the default proxy role can be set with proxy address(0) * @param _address operator address */ function hasProxyPrivilege(address _address, address _proxy, bytes4 _privilege) public view returns (bool) { OperatorData storage data = operators[_address]; bytes32 role = (data.proxyRoles[_proxy] != bytes32(0)) ? data.proxyRoles[_proxy] : data.proxyRoles[ALL_PROXIES]; return (role == ALL_PRIVILEGES) || roles[role].privileges[_privilege]; } } // File: contracts/util/convert/BytesConvert.sol pragma solidity >=0.5.0 <0.6.0; /** * @title BytesConvert * @dev Convert bytes into different types * * @author Cyril Lapinte - <[email protected]> * * Error Messages: * BC01: source must be a valid 32-bytes length * BC02: source must not be greater than 32-bytes **/ library BytesConvert { /** * @dev toUint256 */ function toUint256(bytes memory _source) internal pure returns (uint256 result) { require(_source.length == 32, "BC01"); // solhint-disable-next-line no-inline-assembly assembly { result := mload(add(_source, 0x20)) } } /** * @dev toBytes32 */ function toBytes32(bytes memory _source) internal pure returns (bytes32 result) { require(_source.length <= 32, "BC02"); // solhint-disable-next-line no-inline-assembly assembly { result := mload(add(_source, 0x20)) } } } // File: contracts/abstract/Core.sol pragma solidity >=0.5.0 <0.6.0; /** * @title Core * @dev Solidity version 0.5.x prevents to mark as view * @dev functions using delegate call. * * @author Cyril Lapinte - <[email protected]> * * Error messages * CO01: Only Proxy may access the function * CO02: The proxy has no delegates * CO03: Delegatecall should be successfull * CO04: Invalid delegateId * CO05: Proxy must exist **/ contract Core is Storage { using BytesConvert for bytes; modifier onlyProxy { require(proxyDelegates[msg.sender] != address(0), "CO01"); _; } function delegateCall(address _proxy) internal returns (bool status) { address delegate = proxyDelegates[_proxy]; require(delegate != address(0), "CO02"); // solhint-disable-next-line avoid-low-level-calls (status, ) = delegate.delegatecall(msg.data); require(status, "CO03"); } function delegateCallUint256(address _proxy) internal returns (uint256) { return delegateCallBytes(_proxy).toUint256(); } function delegateCallBytes(address _proxy) internal returns (bytes memory result) { bool status; address delegate = proxyDelegates[_proxy]; require(delegate != address(0), "CO04"); // solhint-disable-next-line avoid-low-level-calls (status, result) = delegate.delegatecall(msg.data); require(status, "CO03"); } function defineProxy( address _proxy, uint256 _delegateId) internal returns (bool) { require(_delegateId < delegates.length, "CO04"); address delegate = delegates[_delegateId]; require(_proxy != address(0), "CO05"); proxyDelegates[_proxy] = delegate; return true; } function removeProxy(address _proxy) internal returns (bool) { delete proxyDelegates[_proxy]; return true; } } // File: contracts/operable/OperableCore.sol pragma solidity >=0.5.0 <0.6.0; /** * @title OperableCore * @dev The Operable contract enable the restrictions of operations to a set of operators * * @author Cyril Lapinte - <[email protected]> * * Error messages * OC01: Sender is not a system operator * OC02: Sender is not a core operator * OC03: Sender is not a proxy operator * OC04: AllPrivileges is a reserved role */ contract OperableCore is Core, OperableStorage { constructor() public { operators[msg.sender].coreRole = ALL_PRIVILEGES; operators[msg.sender].proxyRoles[ALL_PROXIES] = ALL_PRIVILEGES; } /** * @dev onlySysOp modifier * @dev for safety reason, core owner * @dev can always define roles and assign or revoke operatos */ modifier onlySysOp() { require(msg.sender == owner || hasCorePrivilege(msg.sender, msg.sig), "OC01"); _; } /** * @dev onlyCoreOp modifier */ modifier onlyCoreOp() { require(hasCorePrivilege(msg.sender, msg.sig), "OC02"); _; } /** * @dev onlyProxyOp modifier */ modifier onlyProxyOp(address _proxy) { require(hasProxyPrivilege(msg.sender, _proxy, msg.sig), "OC03"); _; } /** * @dev defineRoles * @param _role operator role * @param _privileges as 4 bytes of the method */ function defineRole(bytes32 _role, bytes4[] memory _privileges) public onlySysOp returns (bool) { require(_role != ALL_PRIVILEGES, "OC04"); delete roles[_role]; for (uint256 i=0; i < _privileges.length; i++) { roles[_role].privileges[_privileges[i]] = true; } emit RoleDefined(_role); return true; } /** * @dev assignOperators * @param _role operator role. May be a role not defined yet. * @param _operators addresses */ function assignOperators(bytes32 _role, address[] memory _operators) public onlySysOp returns (bool) { for (uint256 i=0; i < _operators.length; i++) { operators[_operators[i]].coreRole = _role; emit OperatorAssigned(_role, _operators[i]); } return true; } /** * @dev assignProxyOperators * @param _role operator role. May be a role not defined yet. * @param _operators addresses */ function assignProxyOperators( address _proxy, bytes32 _role, address[] memory _operators) public onlySysOp returns (bool) { for (uint256 i=0; i < _operators.length; i++) { operators[_operators[i]].proxyRoles[_proxy] = _role; emit ProxyOperatorAssigned(_proxy, _role, _operators[i]); } return true; } /** * @dev removeOperator * @param _operators addresses */ function revokeOperators(address[] memory _operators) public onlySysOp returns (bool) { for (uint256 i=0; i < _operators.length; i++) { delete operators[_operators[i]]; emit OperatorRevoked(_operators[i]); } return true; } event RoleDefined(bytes32 role); event OperatorAssigned(bytes32 role, address operator); event ProxyOperatorAssigned(address proxy, bytes32 role, address operator); event OperatorRevoked(address operator); } // File: contracts/abstract/Proxy.sol pragma solidity >=0.5.0 <0.6.0; /** * @title Proxy * * @author Cyril Lapinte - <[email protected]> * * Error messages * PR01: Only accessible by core **/ contract Proxy { address public core; /** * @dev Throws if called by any account other than a proxy */ modifier onlyCore { require(core == msg.sender, "PR01"); _; } constructor(address _core) public { core = _core; } } // File: contracts/operable/OperableProxy.sol pragma solidity >=0.5.0 <0.6.0; /** * @title OperableProxy * @dev The OperableAs contract enable the restrictions of operations to a set of operators * @dev It relies on another Operable contract and reuse the same list of operators * * @author Cyril Lapinte - <[email protected]> * * Error messages * OP01: Message sender must be authorized */ contract OperableProxy is Proxy { // solhint-disable-next-line no-empty-blocks constructor(address _core) public Proxy(_core) { } /** * @dev rely on the core configuration for ownership */ function owner() public view returns (address) { return OperableCore(core).owner(); } /** * @dev Throws if called by any account other than the operator */ modifier onlyOperator { require(OperableCore(core).hasProxyPrivilege( msg.sender, address(this), msg.sig), "OP01"); _; } } // File: contracts/util/math/SafeMath.sol pragma solidity >=0.5.0 <0.6.0; /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { // Gas optimization: this is cheaper than asserting 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } c = a * b; assert(c / a == b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 // uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return a / b; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; assert(c >= a); return c; } } // File: contracts/interface/IRule.sol pragma solidity >=0.5.0 <0.6.0; /** * @title IRule * @dev IRule interface * @author Cyril Lapinte - <[email protected]> **/ interface IRule { function isAddressValid(address _address) external view returns (bool); function isTransferValid(address _from, address _to, uint256 _amount) external view returns (bool); } // File: contracts/interface/IClaimable.sol pragma solidity >=0.5.0 <0.6.0; /** * @title IClaimable * @dev IClaimable interface * @author Cyril Lapinte - <[email protected]> **/ contract IClaimable { function hasClaimsSince(address _address, uint256 at) external view returns (bool); } // File: contracts/interface/IUserRegistry.sol pragma solidity >=0.5.0 <0.6.0; /** * @title IUserRegistry * @dev IUserRegistry interface * @author Cyril Lapinte - <[email protected]> **/ contract IUserRegistry { event UserRegistered(uint256 indexed userId); event AddressAttached(uint256 indexed userId, address address_); event AddressDetached(uint256 indexed userId, address address_); function registerManyUsersExternal(address[] calldata _addresses, uint256 _validUntilTime) external returns (bool); function registerManyUsersFullExternal( address[] calldata _addresses, uint256 _validUntilTime, uint256[] calldata _values) external returns (bool); function attachManyAddressesExternal(uint256[] calldata _userIds, address[] calldata _addresses) external returns (bool); function detachManyAddressesExternal(address[] calldata _addresses) external returns (bool); function suspendManyUsers(uint256[] calldata _userIds) external returns (bool); function unsuspendManyUsersExternal(uint256[] calldata _userIds) external returns (bool); function updateManyUsersExternal( uint256[] calldata _userIds, uint256 _validUntilTime, bool _suspended) external returns (bool); function updateManyUsersExtendedExternal( uint256[] calldata _userIds, uint256 _key, uint256 _value) external returns (bool); function updateManyUsersAllExtendedExternal( uint256[] calldata _userIds, uint256[] calldata _values) external returns (bool); function updateManyUsersFullExternal( uint256[] calldata _userIds, uint256 _validUntilTime, bool _suspended, uint256[] calldata _values) external returns (bool); function name() public view returns (string memory); function currency() public view returns (bytes32); function userCount() public view returns (uint256); function userId(address _address) public view returns (uint256); function validUserId(address _address) public view returns (uint256); function validUser(address _address, uint256[] memory _keys) public view returns (uint256, uint256[] memory); function validity(uint256 _userId) public view returns (uint256, bool); function extendedKeys() public view returns (uint256[] memory); function extended(uint256 _userId, uint256 _key) public view returns (uint256); function manyExtended(uint256 _userId, uint256[] memory _key) public view returns (uint256[] memory); function isAddressValid(address _address) public view returns (bool); function isValid(uint256 _userId) public view returns (bool); function defineExtendedKeys(uint256[] memory _extendedKeys) public returns (bool); function registerUser(address _address, uint256 _validUntilTime) public returns (bool); function registerUserFull( address _address, uint256 _validUntilTime, uint256[] memory _values) public returns (bool); function attachAddress(uint256 _userId, address _address) public returns (bool); function detachAddress(address _address) public returns (bool); function detachSelf() public returns (bool); function detachSelfAddress(address _address) public returns (bool); function suspendUser(uint256 _userId) public returns (bool); function unsuspendUser(uint256 _userId) public returns (bool); function updateUser(uint256 _userId, uint256 _validUntilTime, bool _suspended) public returns (bool); function updateUserExtended(uint256 _userId, uint256 _key, uint256 _value) public returns (bool); function updateUserAllExtended(uint256 _userId, uint256[] memory _values) public returns (bool); function updateUserFull( uint256 _userId, uint256 _validUntilTime, bool _suspended, uint256[] memory _values) public returns (bool); } // File: contracts/interface/IRatesProvider.sol pragma solidity >=0.5.0 <0.6.0; /** * @title IRatesProvider * @dev IRatesProvider interface * * @author Cyril Lapinte - <[email protected]> */ contract IRatesProvider { function defineRatesExternal(uint256[] calldata _rates) external returns (bool); function name() public view returns (string memory); function rate(bytes32 _currency) public view returns (uint256); function currencies() public view returns (bytes32[] memory, uint256[] memory, uint256); function rates() public view returns (uint256, uint256[] memory); function convert(uint256 _amount, bytes32 _fromCurrency, bytes32 _toCurrency) public view returns (uint256); function defineCurrencies( bytes32[] memory _currencies, uint256[] memory _decimals, uint256 _rateOffset) public returns (bool); function defineRates(uint256[] memory _rates) public returns (bool); event RateOffset(uint256 rateOffset); event Currencies(bytes32[] currencies, uint256[] decimals); event Rate(uint256 at, bytes32 indexed currency, uint256 rate); } // File: contracts/TokenStorage.sol pragma solidity >=0.5.0 <0.6.0; /** * @title Token storage * @dev Token storage * @author Cyril Lapinte - <[email protected]> */ contract TokenStorage is OperableStorage { using SafeMath for uint256; enum TransferCode { UNKNOWN, OK, INVALID_SENDER, NO_RECIPIENT, INSUFFICIENT_TOKENS, LOCKED, FROZEN, RULE, LIMITED_RECEPTION } struct Proof { uint256 amount; uint64 startAt; uint64 endAt; } struct AuditData { uint64 createdAt; uint64 lastTransactionAt; uint64 lastEmissionAt; uint64 lastReceptionAt; uint256 cumulatedEmission; uint256 cumulatedReception; } struct AuditStorage { mapping (address => bool) selector; AuditData sharedData; mapping(uint256 => AuditData) userData; mapping(address => AuditData) addressData; } struct Lock { uint256 startAt; uint256 endAt; mapping(address => bool) exceptions; } struct TokenData { string name; string symbol; uint256 decimals; uint256 totalSupply; mapping (address => uint256) balances; mapping (address => mapping (address => uint256)) allowed; bool mintingFinished; uint256 allTimeIssued; // potential overflow uint256 allTimeRedeemed; // potential overflow uint256 allTimeSeized; // potential overflow mapping (address => Proof[]) proofs; mapping (address => uint256) frozenUntils; Lock lock; IRule[] rules; IClaimable[] claimables; } mapping (address => TokenData) internal tokens_; mapping (address => mapping (uint256 => AuditStorage)) internal audits; IUserRegistry internal userRegistry; IRatesProvider internal ratesProvider; bytes32 internal currency; uint256[] internal userKeys; string internal name_; /** * @dev currentTime() */ function currentTime() internal view returns (uint64) { // solhint-disable-next-line not-rely-on-time return uint64(now); } event OraclesDefined( IUserRegistry userRegistry, IRatesProvider ratesProvider, bytes32 currency, uint256[] userKeys); event AuditSelectorDefined( address indexed scope, uint256 scopeId, address[] addresses, bool[] values); event Issue(address indexed token, uint256 amount); event Redeem(address indexed token, uint256 amount); event Mint(address indexed token, uint256 amount); event MintFinished(address indexed token); event ProofCreated(address indexed token, address indexed holder, uint256 proofId); event RulesDefined(address indexed token, IRule[] rules); event LockDefined( address indexed token, uint256 startAt, uint256 endAt, address[] exceptions ); event Seize(address indexed token, address account, uint256 amount); event Freeze(address address_, uint256 until); event ClaimablesDefined(address indexed token, IClaimable[] claimables); event TokenDefined( address indexed token, uint256 delegateId, string name, string symbol, uint256 decimals); event TokenRemoved(address indexed token); } // File: contracts/interface/ITokenCore.sol pragma solidity >=0.5.0 <0.6.0; /** * @title ITokenCore * * @author Cyril Lapinte - <[email protected]> * * Error messages **/ contract ITokenCore { function name() public view returns (string memory); function oracles() public view returns (IUserRegistry, IRatesProvider, bytes32, uint256[] memory); function auditSelector( address _scope, uint256 _scopeId, address[] memory _addresses) public view returns (bool[] memory); function auditShared( address _scope, uint256 _scopeId) public view returns ( uint64 createdAt, uint64 lastTransactionAt, uint64 lastEmissionAt, uint64 lastReceptionAt, uint256 cumulatedEmission, uint256 cumulatedReception); function auditUser( address _scope, uint256 _scopeId, uint256 _userId) public view returns ( uint64 createdAt, uint64 lastTransactionAt, uint64 lastEmissionAt, uint64 lastReceptionAt, uint256 cumulatedEmission, uint256 cumulatedReception); function auditAddress( address _scope, uint256 _scopeId, address _holder) public view returns ( uint64 createdAt, uint64 lastTransactionAt, uint64 lastEmissionAt, uint64 lastReceptionAt, uint256 cumulatedEmission, uint256 cumulatedReception); /*********** TOKEN DATA ***********/ function token(address _token) public view returns ( bool mintingFinished, uint256 allTimeIssued, uint256 allTimeRedeemed, uint256 allTimeSeized, uint256[2] memory lock, uint256 freezedUntil, IRule[] memory, IClaimable[] memory); function tokenProofs(address _token, address _holder, uint256 _proofId) public view returns (uint256, uint64, uint64); function canTransfer(address, address, uint256) public returns (uint256); /*********** TOKEN ADMIN ***********/ function issue(address, uint256) public returns (bool); function redeem(address, uint256) public returns (bool); function mint(address, address, uint256) public returns (bool); function finishMinting(address) public returns (bool); function mintAtOnce(address, address[] memory, uint256[] memory) public returns (bool); function seize(address _token, address, uint256) public returns (bool); function freezeManyAddresses( address _token, address[] memory _addresses, uint256 _until) public returns (bool); function createProof(address, address) public returns (bool); function defineLock(address, uint256, uint256, address[] memory) public returns (bool); function defineRules(address, IRule[] memory) public returns (bool); function defineClaimables(address, IClaimable[] memory) public returns (bool); /************ CORE ADMIN ************/ function defineToken( address _token, uint256 _delegateId, string memory _name, string memory _symbol, uint256 _decimals) public returns (bool); function removeToken(address _token) public returns (bool); function defineOracles( IUserRegistry _userRegistry, IRatesProvider _ratesProvider, uint256[] memory _userKeys) public returns (bool); function defineAuditSelector( address _scope, uint256 _scopeId, address[] memory _selectorAddresses, bool[] memory _selectorValues) public returns (bool); event OraclesDefined( IUserRegistry userRegistry, IRatesProvider ratesProvider, bytes32 currency, uint256[] userKeys); event AuditSelectorDefined( address indexed scope, uint256 scopeId, address[] addresses, bool[] values); event Issue(address indexed token, uint256 amount); event Redeem(address indexed token, uint256 amount); event Mint(address indexed token, uint256 amount); event MintFinished(address indexed token); event ProofCreated(address indexed token, address holder, uint256 proofId); event RulesDefined(address indexed token, IRule[] rules); event LockDefined( address indexed token, uint256 startAt, uint256 endAt, address[] exceptions ); event Seize(address indexed token, address account, uint256 amount); event Freeze(address address_, uint256 until); event ClaimablesDefined(address indexed token, IClaimable[] claimables); event TokenDefined( address indexed token, uint256 delegateId, string name, string symbol, uint256 decimals); event TokenRemoved(address indexed token); } // File: contracts/TokenCore.sol pragma solidity >=0.5.0 <0.6.0; /** * @title TokenCore * * @author Cyril Lapinte - <[email protected]> * * Error messages * TC01: Currency stored values must remain consistent * TC02: The audit selector definition requires the same number of addresses and values **/ contract TokenCore is ITokenCore, OperableCore, TokenStorage { /** * @dev constructor * * @dev It is desired for now that delegates * @dev cannot be changed once the core has been deployed. */ constructor(string memory _name, address[] memory _delegates) public { name_ = _name; delegates = _delegates; } function name() public view returns (string memory) { return name_; } function oracles() public view returns (IUserRegistry, IRatesProvider, bytes32, uint256[] memory) { return (userRegistry, ratesProvider, currency, userKeys); } function auditSelector( address _scope, uint256 _scopeId, address[] memory _addresses) public view returns (bool[] memory) { AuditStorage storage auditStorage = audits[_scope][_scopeId]; bool[] memory selector = new bool[](_addresses.length); for (uint256 i=0; i < _addresses.length; i++) { selector[i] = auditStorage.selector[_addresses[i]]; } return selector; } function auditShared( address _scope, uint256 _scopeId) public view returns ( uint64 createdAt, uint64 lastTransactionAt, uint64 lastEmissionAt, uint64 lastReceptionAt, uint256 cumulatedEmission, uint256 cumulatedReception) { AuditData memory audit = audits[_scope][_scopeId].sharedData; createdAt = audit.createdAt; lastTransactionAt = audit.lastTransactionAt; lastReceptionAt = audit.lastReceptionAt; lastEmissionAt = audit.lastEmissionAt; cumulatedReception = audit.cumulatedReception; cumulatedEmission = audit.cumulatedEmission; } function auditUser( address _scope, uint256 _scopeId, uint256 _userId) public view returns ( uint64 createdAt, uint64 lastTransactionAt, uint64 lastEmissionAt, uint64 lastReceptionAt, uint256 cumulatedEmission, uint256 cumulatedReception) { AuditData memory audit = audits[_scope][_scopeId].userData[_userId]; createdAt = audit.createdAt; lastTransactionAt = audit.lastTransactionAt; lastReceptionAt = audit.lastReceptionAt; lastEmissionAt = audit.lastEmissionAt; cumulatedReception = audit.cumulatedReception; cumulatedEmission = audit.cumulatedEmission; } function auditAddress( address _scope, uint256 _scopeId, address _holder) public view returns ( uint64 createdAt, uint64 lastTransactionAt, uint64 lastEmissionAt, uint64 lastReceptionAt, uint256 cumulatedEmission, uint256 cumulatedReception) { AuditData memory audit = audits[_scope][_scopeId].addressData[_holder]; createdAt = audit.createdAt; lastTransactionAt = audit.lastTransactionAt; lastReceptionAt = audit.lastReceptionAt; lastEmissionAt = audit.lastEmissionAt; cumulatedReception = audit.cumulatedReception; cumulatedEmission = audit.cumulatedEmission; } /************** ERC20 **************/ function tokenName() public view returns (string memory) { return tokens_[msg.sender].name; } function tokenSymbol() public view returns (string memory) { return tokens_[msg.sender].symbol; } function tokenDecimals() public view returns (uint256) { return tokens_[msg.sender].decimals; } function tokenTotalSupply() public view returns (uint256) { return tokens_[msg.sender].totalSupply; } function tokenBalanceOf(address _owner) public view returns (uint256) { return tokens_[msg.sender].balances[_owner]; } function tokenAllowance(address _owner, address _spender) public view returns (uint256) { return tokens_[msg.sender].allowed[_owner][_spender]; } function transfer(address, address, uint256) public onlyProxy returns (bool status) { return delegateCall(msg.sender); } function transferFrom(address, address, address, uint256) public onlyProxy returns (bool status) { return delegateCall(msg.sender); } function approve(address, address, uint256) public onlyProxy returns (bool status) { return delegateCall(msg.sender); } function increaseApproval(address, address, uint256) public onlyProxy returns (bool status) { return delegateCall(msg.sender); } function decreaseApproval(address, address, uint256) public onlyProxy returns (bool status) { return delegateCall(msg.sender); } function canTransfer(address, address, uint256) public onlyProxy returns (uint256) { return delegateCallUint256(msg.sender); } /*********** TOKEN DATA ***********/ function token(address _token) public view returns ( bool mintingFinished, uint256 allTimeIssued, uint256 allTimeRedeemed, uint256 allTimeSeized, uint256[2] memory lock, uint256 frozenUntil, IRule[] memory rules, IClaimable[] memory claimables) { TokenData storage tokenData = tokens_[_token]; mintingFinished = tokenData.mintingFinished; allTimeIssued = tokenData.allTimeIssued; allTimeRedeemed = tokenData.allTimeRedeemed; allTimeSeized = tokenData.allTimeSeized; lock = [ tokenData.lock.startAt, tokenData.lock.endAt ]; frozenUntil = tokenData.frozenUntils[msg.sender]; rules = tokenData.rules; claimables = tokenData.claimables; } function tokenProofs(address _token, address _holder, uint256 _proofId) public view returns (uint256, uint64, uint64) { Proof[] storage proofs = tokens_[_token].proofs[_holder]; if (_proofId < proofs.length) { Proof storage proof = proofs[_proofId]; return (proof.amount, proof.startAt, proof.endAt); } return (uint256(0), uint64(0), uint64(0)); } /*********** TOKEN ADMIN ***********/ function issue(address _token, uint256) public onlyProxyOp(_token) returns (bool) { return delegateCall(_token); } function redeem(address _token, uint256) public onlyProxyOp(_token) returns (bool) { return delegateCall(_token); } function mint(address _token, address, uint256) public onlyProxyOp(_token) returns (bool) { return delegateCall(_token); } function finishMinting(address _token) public onlyProxyOp(_token) returns (bool) { return delegateCall(_token); } function mintAtOnce(address _token, address[] memory, uint256[] memory) public onlyProxyOp(_token) returns (bool) { return delegateCall(_token); } function seize(address _token, address, uint256) public onlyProxyOp(_token) returns (bool) { return delegateCall(_token); } function freezeManyAddresses( address _token, address[] memory, uint256) public onlyProxyOp(_token) returns (bool) { return delegateCall(_token); } function createProof(address _token, address) public returns (bool) { return delegateCall(_token); } function defineLock(address _token, uint256, uint256, address[] memory) public onlyProxyOp(_token) returns (bool) { return delegateCall(_token); } function defineRules(address _token, IRule[] memory) public onlyProxyOp(_token) returns (bool) { return delegateCall(_token); } function defineClaimables(address _token, IClaimable[] memory) public onlyProxyOp(_token) returns (bool) { return delegateCall(_token); } /************ CORE ADMIN ************/ function defineToken( address _token, uint256 _delegateId, string memory _name, string memory _symbol, uint256 _decimals) public onlyCoreOp returns (bool) { defineProxy(_token, _delegateId); TokenData storage tokenData = tokens_[_token]; tokenData.name = _name; tokenData.symbol = _symbol; tokenData.decimals = _decimals; emit TokenDefined(_token, _delegateId, _name, _symbol, _decimals); return true; } function removeToken(address _token) public onlyCoreOp returns (bool) { removeProxy(_token); delete tokens_[_token]; emit TokenRemoved(_token); return true; } function defineOracles( IUserRegistry _userRegistry, IRatesProvider _ratesProvider, uint256[] memory _userKeys) public onlyCoreOp returns (bool) { if (currency != bytes32(0)) { // Updating the core currency is not yet supported require(_userRegistry.currency() == currency, "TC01"); } else { currency = _userRegistry.currency(); } userRegistry = _userRegistry; ratesProvider = _ratesProvider; userKeys = _userKeys; emit OraclesDefined(userRegistry, ratesProvider, currency, userKeys); return true; } function defineAuditSelector( address _scope, uint256 _scopeId, address[] memory _selectorAddresses, bool[] memory _selectorValues) public onlyCoreOp returns (bool) { require(_selectorAddresses.length == _selectorValues.length, "TC02"); AuditStorage storage auditStorage = audits[_scope][_scopeId]; for (uint256 i=0; i < _selectorAddresses.length; i++) { auditStorage.selector[_selectorAddresses[i]] = _selectorValues[i]; } emit AuditSelectorDefined(_scope, _scopeId, _selectorAddresses, _selectorValues); return true; } } // File: contracts/interface/IERC20.sol pragma solidity >=0.5.0 <0.6.0; /** * @title ERC20 interface * @dev ERC20 interface */ contract IERC20 { function name() public view returns (string memory); function symbol() public view returns (string memory); function decimals() public view returns (uint256); function totalSupply() public view returns (uint256); function balanceOf(address _owner) public view returns (uint256); function allowance(address _owner, address _spender) public view returns (uint256); function transfer(address _to, uint256 _value) public returns (bool); function transferFrom(address _from, address _to, uint256 _value) public returns (bool); function approve(address _spender, uint256 _value) public returns (bool); function increaseApproval(address _spender, uint _addedValue) public returns (bool); function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); } // File: contracts/TokenProxy.sol pragma solidity >=0.5.0 <0.6.0; /** * @title Token proxy * @dev Token proxy default implementation * @author Cyril Lapinte - <[email protected]> */ contract TokenProxy is IERC20, OperableProxy { // solhint-disable-next-line no-empty-blocks constructor(address _core) public OperableProxy(_core) { } function name() public view returns (string memory) { return TokenCore(core).tokenName(); } function symbol() public view returns (string memory) { return TokenCore(core).tokenSymbol(); } function decimals() public view returns (uint256) { return TokenCore(core).tokenDecimals(); } function totalSupply() public view returns (uint256) { return TokenCore(core).tokenTotalSupply(); } function balanceOf(address _owner) public view returns (uint256) { return TokenCore(core).tokenBalanceOf(_owner); } function allowance(address _owner, address _spender) public view returns (uint256) { return TokenCore(core).tokenAllowance(_owner, _spender); } function transfer(address _to, uint256 _value) public returns (bool status) { return TokenCore(core).transfer(msg.sender, _to, _value); } function transferFrom(address _from, address _to, uint256 _value) public returns (bool status) { return TokenCore(core).transferFrom(msg.sender, _from, _to, _value); } function approve(address _spender, uint256 _value) public returns (bool status) { return TokenCore(core).approve(msg.sender, _spender, _value); } function increaseApproval(address _spender, uint256 _addedValue) public returns (bool status) { return TokenCore(core).increaseApproval(msg.sender, _spender, _addedValue); } function decreaseApproval(address _spender, uint256 _subtractedValue) public returns (bool status) { return TokenCore(core).decreaseApproval(msg.sender, _spender, _subtractedValue); } function canTransfer(address _from, address _to, uint256 _value) public returns (uint256) { return TokenCore(core).canTransfer(_from, _to, _value); } function emitTransfer(address _from, address _to, uint256 _value) public onlyCore returns (bool) { emit Transfer(_from, _to, _value); return true; } function emitApproval(address _owner, address _spender, uint256 _value) public onlyCore returns (bool) { emit Approval(_owner, _spender, _value); return true; } event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); }
Read Contract
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
core 0xf2f4eb26 → address
decimals 0x313ce567 → uint256
name 0x06fdde03 → string
owner 0x8da5cb5b → address
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256
Write Contract 8 functions
These functions modify contract state and require a wallet transaction to execute.
approve 0x095ea7b3
address _spender
uint256 _value
returns: bool
canTransfer 0xe46638e6
address _from
address _to
uint256 _value
returns: uint256
decreaseApproval 0x66188463
address _spender
uint256 _subtractedValue
returns: bool
emitApproval 0x5687f2b8
address _owner
address _spender
uint256 _value
returns: bool
emitTransfer 0x23de6651
address _from
address _to
uint256 _value
returns: bool
increaseApproval 0xd73dd623
address _spender
uint256 _addedValue
returns: bool
transfer 0xa9059cbb
address _to
uint256 _value
returns: bool
transferFrom 0x23b872dd
address _from
address _to
uint256 _value
returns: bool
Top Interactions
| Address | Txns | Sent | Received |
|---|---|---|---|
| 0x759070A2...AD7D | 1 | 1 |
Recent Transactions
|
| Hash | Block | Age | From/To | Value | |
|---|---|---|---|---|---|
| 0xe9eb0d5b...a62a81 Fail | 10,630,593 | IN | 0x759070A2...AD7D | 0 ETH |