Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 72 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 12919428 | 1268 days ago | IN | 0 ETH | 0.00215814 | ||||
Deposit | 12064707 | 1401 days ago | IN | 0.0238 ETH | 0.03060995 | ||||
Withdraw | 11999052 | 1411 days ago | IN | 0 ETH | 0.0121876 | ||||
Deposit | 11992562 | 1412 days ago | IN | 0.0535 ETH | 0.02719233 | ||||
Withdraw | 11992527 | 1412 days ago | IN | 0 ETH | 0.01096884 | ||||
Deposit | 11991299 | 1412 days ago | IN | 0.0428 ETH | 0.02332451 | ||||
Withdraw | 11356073 | 1510 days ago | IN | 0 ETH | 0.00109666 | ||||
Deposit | 11349573 | 1511 days ago | IN | 0.045 ETH | 0.00466463 | ||||
Withdraw | 11086731 | 1551 days ago | IN | 0 ETH | 0.01005316 | ||||
Withdraw | 10717016 | 1608 days ago | IN | 0 ETH | 0.00548442 | ||||
Deposit | 10717002 | 1608 days ago | IN | 0.20926674 ETH | 0.01908369 | ||||
Deposit | 10679973 | 1614 days ago | IN | 0 ETH | 0.02000283 | ||||
Withdraw | 10431723 | 1652 days ago | IN | 0 ETH | 0.00237658 | ||||
Deposit | 10425873 | 1653 days ago | IN | 1 ETH | 0.00906411 | ||||
Redeem | 10243053 | 1681 days ago | IN | 0 ETH | 0.00215665 | ||||
Initiate | 10243017 | 1681 days ago | IN | 0 ETH | 0.01063677 | ||||
Deposit | 10240141 | 1682 days ago | IN | 1.575 ETH | 0.00430916 | ||||
Redeem | 10239915 | 1682 days ago | IN | 0 ETH | 0.00209674 | ||||
Initiate | 10239881 | 1682 days ago | IN | 0 ETH | 0.01034131 | ||||
Deposit | 10239405 | 1682 days ago | IN | 1.575 ETH | 0.00698382 | ||||
Withdraw | 10239375 | 1682 days ago | IN | 0 ETH | 0.00286408 | ||||
Deposit | 10239067 | 1682 days ago | IN | 1.6 ETH | 0.0074296 | ||||
Redeem | 10161921 | 1694 days ago | IN | 0 ETH | 0.0023958 | ||||
Initiate | 10161883 | 1694 days ago | IN | 0 ETH | 0.01181816 | ||||
Deposit | 10161237 | 1694 days ago | IN | 1.35 ETH | 0.00594368 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
12919428 | 1268 days ago | 0.0238 ETH | ||||
11999052 | 1411 days ago | 0.0535 ETH | ||||
11992527 | 1412 days ago | 0.0428 ETH | ||||
11356073 | 1510 days ago | 0.045 ETH | ||||
10717016 | 1608 days ago | 0.20926674 ETH | ||||
10431723 | 1652 days ago | 1 ETH | ||||
10243053 | 1681 days ago | 1.575 ETH | ||||
10239915 | 1682 days ago | 1.575 ETH | ||||
10239375 | 1682 days ago | 1.6 ETH | ||||
10161921 | 1694 days ago | 1.35 ETH | ||||
10160978 | 1694 days ago | 12.625 ETH | ||||
10139550 | 1697 days ago | 7 ETH | ||||
10123161 | 1700 days ago | 2.58 ETH | ||||
10122978 | 1700 days ago | 2.022 ETH | ||||
10122705 | 1700 days ago | 2.025 ETH | ||||
10122609 | 1700 days ago | 0.045 ETH | ||||
10115964 | 1701 days ago | 3.2 ETH | ||||
10115867 | 1701 days ago | 3.2625 ETH | ||||
10115200 | 1701 days ago | 0.175 ETH | ||||
10113383 | 1701 days ago | 0.84 ETH | ||||
10113363 | 1701 days ago | 0.858 ETH | ||||
10113363 | 1701 days ago | 1.56 ETH | ||||
10113344 | 1701 days ago | 0.1875 ETH | ||||
10113295 | 1701 days ago | 0.8316 ETH | ||||
9598188 | 1781 days ago | 0.27 ETH |
Loading...
Loading
Contract Name:
AdminUpgradeabilityProxy
Compiler Version
v0.5.12+commit.7709ece9
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-02-19 */ pragma solidity 0.5.12; /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two unsigned integers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // 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-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } /** * Utility library of inline functions on addresses */ library Address { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param account address of the account to check * @return whether the target address is a contract */ function isContract(address account) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 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 GSN 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. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgValue() internal view returns (uint256) { return msg.value; } } /** * @title ERC20 interface * @dev see https://eips.ethereum.org/EIPS/eip-20 */ interface IERC20 { function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require((value == 0) || (token.allowance(address(this), spender) == 0)); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must equal true). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. require(address(token).isContract()); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool))); } } } /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor () internal { _owner = _msgSender(); emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return _msgSender() == _owner; } /** * @dev Allows the current owner to relinquish control of the contract. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. * @notice Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _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)); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } /** * @title EternalStorage * @dev Store the all information about users and orders */ contract EternalStorage is Ownable { // Count of users who is or was active uint256 internal _usersCount; // Count of deposits uint256 internal _depositsCount; // Count of swaps uint256 internal _swapsCount; // The id for ETH asset is 0x0 address // the rest assets should have their token contract address address internal _ethAssetIdentificator = address(0); // Order details which is available by JAVA long number struct OrderDetails { // does the order has been deposited bool created; // the 0x0 for Ethereum and ERC contract address for tokens address asset; // tokens/eth amount uint256 amount; // the status (deposited/withdrawn) bool withdrawn; // creation timestamp uint256 initTimestamp; } // Each user has his own state and details struct User { // user exist validation bool bool exist; // contract order index uint256 index; // contract index (0, 1, 2 ...) => exchange order number (JAVA long number) mapping(uint256 => uint256) orderIdByIndex; // JAVA long number => order details mapping(uint256 => OrderDetails) orders; } // the body of each swap struct Swap { uint256 initTimestamp; uint256 refundTimestamp; bytes32 secretHash; bytes32 secret; address initiator; address recipient; address asset; uint256 amount; uint256 orderId; State state; } // struct of swap Initiator struct Initiator { // contract order index uint256 index; // length of filled swaps uint256 filledSwaps; // index (0, 1, 2 ...) => swap hash mapping(uint256 => bytes32) swaps; } // min/max life limits for swap order // can be changed only by the contract owner struct SwapTimeLimits { uint256 min; uint256 max; } // ETH wallet => Assets => value mapping(address => User) internal _users; // Id => Address of user mapping(uint256 => address) internal _usersById; // Id => Swap secret hash mapping(uint256 => bytes32) internal _swapsById; // Id => Order id mapping(uint256 => uint256) internal _depositsById; // mapping of swaps based on secret hash and swap info mapping(bytes32 => Swap) internal _swaps; // the swaps data by initiator address mapping(address => Initiator) internal _initiators; // swaps' state enum State { Empty, Filled, Redeemed, Refunded } // users can swap ETH and ERC tokens enum SwapType { ETH, Token } // By default, the contract has limits for swap orders lifetime // The swap order can be active from 10 minutes until 6 months SwapTimeLimits internal _swapTimeLimits = SwapTimeLimits(10 minutes, 180 days); // ----------------------------------------- // ADMIN METHODS // ----------------------------------------- /** * @dev The owner can change time limits for swap lifetime * Amounts should be written in MINUTES */ function changeSwapLifetimeLimits( uint256 newMin, uint256 newMax ) external onlyOwner { require(newMin != 0, "changeSwapLifetimeLimits: newMin and newMax should be bigger then 0"); require(newMax >= newMin, "changeSwapLifetimeLimits: the newMax should be bigger then newMax"); _swapTimeLimits = SwapTimeLimits(newMin * 1 minutes, newMax * 1 minutes); } } /** * @title Proxy * @dev Implements delegation of calls to other contracts, with proper * forwarding of return values and bubbling of failures. * It defines a fallback function that delegates all calls to the address * returned by the abstract _implementation() internal function. */ contract Proxy is EternalStorage { /** * @dev Fallback function. * Implemented entirely in `_fallback`. */ function () payable external { _fallback(); } /** * @dev fallback implementation. * Extracted to enable manual triggering. */ function _fallback() internal { _willFallback(); _delegate(_implementation()); } /** * @dev Function that is run as the first thing in the fallback function. * Can be redefined in derived contracts to add functionality. * Redefinitions must call super._willFallback(). */ function _willFallback() internal {} /** * @dev Delegates execution to an implementation contract. * This is a low level function that doesn't return to its internal call site. * It will return to the external caller whatever the implementation returns. * @param implementation Address to delegate. */ function _delegate(address implementation) internal { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize) } default { return(0, returndatasize) } } } /** * @return The Address of the implementation. */ function _implementation() internal view returns (address); } /** * @title BaseUpgradeabilityProxy * @dev This contract implements a proxy that allows to change the * implementation address to which it will delegate. * Such a change is called an implementation upgrade. */ contract BaseUpgradeabilityProxy is Proxy { using Address for address; /** * @dev The version of current(active) logic contract */ string internal _version; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "org.zeppelinos.proxy.implementation", and is * validated in the constructor. */ bytes32 internal constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3; /** * @dev Emitted when the implementation is upgraded. * @param implementation Address of the new implementation. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation. * @return Address of the current implementation */ function _implementation() internal view returns (address impl) { bytes32 slot = IMPLEMENTATION_SLOT; assembly { impl := sload(slot) } } /** * @dev Upgrades the proxy to a new implementation. * @param newImplementation Address of the new implementation. * @param newVersion of proxied contract. */ function _upgradeTo(address newImplementation, string memory newVersion) internal { _setImplementation(newImplementation, newVersion); emit Upgraded(newImplementation); } /** * @dev Sets the implementation address of the proxy. * @param newImplementation Address of the new implementation. * @param newVersion of proxied contract. */ function _setImplementation(address newImplementation, string memory newVersion) internal { require(newImplementation.isContract(), "Cannot set a proxy implementation to a non-contract address"); _version = newVersion; bytes32 slot = IMPLEMENTATION_SLOT; assembly { sstore(slot, newImplementation) } } } /** * @title UpgradeabilityProxy * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing * implementation and init data. */ contract UpgradeabilityProxy is BaseUpgradeabilityProxy { /** * @dev Contract constructor. * @param _logic Address of the initial implementation. */ constructor(address _logic) public payable { assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation")); _setImplementation(_logic, '1.0.0'); } } /** * @title BaseAdminUpgradeabilityProxy * @dev This contract combines an upgradeability proxy with an authorization * mechanism for administrative tasks. * All external functions in this contract must be guarded by the * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity * feature proposal that would enable this to be done automatically. */ contract BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy { /** * @dev Emitted when the administration has been transferred. * @param previousAdmin Address of the previous admin. * @param newAdmin Address of the new admin. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "org.zeppelinos.proxy.admin", and is * validated in the constructor. */ bytes32 internal constant ADMIN_SLOT = 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b; /** * @dev Modifier to check whether the `msg.sender` is the admin. * If it is, it will run the function. Otherwise, it will delegate the call * to the implementation. */ modifier ifAdmin() { if (msg.sender == _admin()) { _; } else { _fallback(); } } /** * @return The address of the proxy admin. */ function admin() external view returns (address) { return _admin(); } /** * @return The version of logic contract */ function version() external view returns (string memory) { return _version; } /** * @return The address of the implementation. */ function implementation() external view returns (address) { return _implementation(); } /** * @dev Changes the admin of the proxy. * Only the current admin can call this function. * @param newAdmin Address to transfer proxy administration to. */ function changeAdmin(address newAdmin) external ifAdmin { require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address"); emit AdminChanged(_admin(), newAdmin); _setAdmin(newAdmin); } /** * @dev Upgrade the backing implementation of the proxy. * Only the admin can call this function. * @param newImplementation Address of the new implementation. * @param newVersion of proxied contract. */ function upgradeTo(address newImplementation, string calldata newVersion) external ifAdmin { _upgradeTo(newImplementation, newVersion); } /** * @dev Upgrade the backing implementation of the proxy and call a function * on the new implementation. * This is useful to initialize the proxied contract. * @param newImplementation Address of the new implementation. * @param newVersion of proxied contract. * @param data Data to send as msg.data in the low level call. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. */ function upgradeToAndCall(address newImplementation, string calldata newVersion, bytes calldata data) payable external ifAdmin { _upgradeTo(newImplementation, newVersion); (bool success,) = newImplementation.delegatecall(data); require(success); } /** * @return The admin slot. */ function _admin() internal view returns (address adm) { bytes32 slot = ADMIN_SLOT; assembly { adm := sload(slot) } } /** * @dev Sets the address of the proxy admin. * @param newAdmin Address of the new proxy admin. */ function _setAdmin(address newAdmin) internal { bytes32 slot = ADMIN_SLOT; assembly { sstore(slot, newAdmin) } } /** * @dev Only fall back when the sender is not the admin. */ function _willFallback() internal { require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin"); super._willFallback(); } } /** * @title AdminUpgradeabilityProxy * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for * initializing the implementation, admin, and init data. */ contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy { /** * Contract constructor. * @param _logic address of the initial implementation. * @param _admin Address of the proxy administrator. */ constructor(address _logic, address _admin) UpgradeabilityProxy(_logic) public payable { assert(ADMIN_SLOT == keccak256("org.zeppelinos.proxy.admin")); _setAdmin(_admin); } } /** * @title AssetsValue * @dev The contract which hold all tokens and ETH as a assets * Also should be responsible for the balance increasing/decreasing and validation */ contract AssetsValue is EternalStorage { // using safe math calculation using SafeMath for uint256; // for being secure during transactions between users and contract gonna use SafeERC20 lib using SafeERC20 for IERC20; modifier orderIdNotExist( uint256 orderId, address user ) { require(_getOrderDetails(orderId, user).created == false, "orderIdNotExist: user already deposit this orderId"); _; } // Events event AssetDeposited(uint256 orderId, address indexed user, address indexed asset, uint256 amount); event AssetWithdrawal(uint256 orderId, address indexed user, address indexed asset, uint256 amount); // ----------------------------------------- // FALLBACK // ----------------------------------------- function () external payable { // reverts all fallback & payable transactions revert("Fallback methods should be reverted"); } // ----------------------------------------- // EXTERNAL // ----------------------------------------- function deposit( uint256 orderId ) public orderIdNotExist(orderId, _msgSender()) payable { require(_msgValue() != 0, "deposit: user needs to transfer ETH for calling this method"); _deposit(orderId, _msgSender(), _ethAssetIdentificator, _msgValue()); } function deposit( uint256 orderId, uint256 amount, address token ) public orderIdNotExist(orderId, _msgSender()) { require(token != address(0), "deposit: invalid token address"); require(amount != 0, "deposit: user needs to fill transferable tokens amount for calling this method"); IERC20(token).safeTransferFrom(_msgSender(), address(this), amount); _deposit(orderId, _msgSender(), token, amount); } function withdraw( uint256 orderId ) external { // validation of the user existion require(_doesUserExist(_msgSender()) == true, "withdraw: the user is not active"); _withdraw(orderId); } // ----------------------------------------- // GETTERS // ----------------------------------------- function doesUserExist( address user ) external view returns (bool) { return _doesUserExist(user); } function getUserActiveDeposits( address user, uint256 cursor, uint256 howMany ) public view returns ( uint256[] memory orderIds, uint256[] memory amounts, uint256[] memory initTimestamps, uint256 newCursor ) { // amount of deposits which user has been done uint256 depositsLength = _users[user].index; uint256 activeOrdersLength = 0; // calculate lenght of necesseary array for (uint256 i = 0; i < depositsLength; i++){ uint256 orderId = _users[user].orderIdByIndex[i]; if (_users[user].orders[orderId].withdrawn == false) { activeOrdersLength++; } } uint256 length = howMany; if (length > activeOrdersLength - cursor) { length = activeOrdersLength - cursor; } // create new arrays with necesseary array lengths orderIds = new uint256[](length); amounts = new uint256[](length); initTimestamps = new uint256[](length); uint256 j = 0; for (uint256 i = 0; i < depositsLength; i++){ if (j == length) { break; } else { uint256 orderId = _users[user].orderIdByIndex[cursor + i]; if (_users[user].orders[orderId].withdrawn == false) { orderIds[j] = orderId; amounts[j] = _users[user].orders[orderId].amount; initTimestamps[j] = _users[user].orders[orderId].initTimestamp; j++; } } } return ( orderIds, amounts, initTimestamps, cursor + length ); } function getUserFilledDeposits( address user, uint256 cursor, uint256 howMany ) external view returns ( uint256[] memory orderIds, uint256[] memory amounts, uint256[] memory initTimestamps, uint256 newCursor ) { // amount of deposits which user has been done uint256 depositsLength = _users[user].index; uint256 length = howMany; if (length > depositsLength - cursor) { length = depositsLength - cursor; } // init empty arrays which should been returned orderIds = new uint256[](length); amounts = new uint256[](length); initTimestamps = new uint256[](length); uint256 j = 0; for (uint256 i = 0; i < length; i++){ uint256 orderId = _users[user].orderIdByIndex[cursor + i]; orderIds[j] = orderId; amounts[j] = _users[user].orders[orderId].amount; initTimestamps[j] = _users[user].orders[orderId].initTimestamp; j++; } return ( orderIds, amounts, initTimestamps, cursor + length ); } function getUserDepositIndex( address user ) external view returns ( uint256 ) { return _users[user].index; } function getOrderDetails( uint256 orderId, address user ) external view returns ( bool created, address asset, uint256 amount, bool withdrawn, uint256 initTimestamp ) { OrderDetails memory order = _getOrderDetails(orderId, user); return ( order.created, order.asset, order.amount, order.withdrawn, order.initTimestamp ); } function getUserById( uint256 userId ) external view returns ( address user ) { return _usersById[userId]; } function getUsersList( uint256 cursor, uint256 howMany ) external view returns ( address[] memory users, uint256 newCursor ) { uint256 length = howMany; if (length > _usersCount - cursor) { length = _usersCount - cursor; } users = new address[](length); for (uint256 i = 0; i < length; i++) { users[i] = _usersById[cursor + i]; } return (users, cursor + length); } function getUsersCount() external view returns (uint256 count) { return _usersCount; } // ----------------------------------------- // INTERNAL // ----------------------------------------- function _deposit( uint256 orderId, address sender, address asset, uint256 amount ) internal { _activateIfUserIsNew(sender); _depositOrderBalance(orderId, sender, asset, amount); // Increase user deposits count _users[sender].index += 1; // Update deposits mapping and count _depositsById[_depositsCount] = orderId; _depositsCount++; emit AssetDeposited(orderId, sender, asset, amount); } function _withdraw( uint256 orderId ) internal { // storing the order information (asset and amount) OrderDetails memory order = _getOrderDetails(orderId, _msgSender()); address asset = order.asset; uint256 amount = order.amount; // validations before withdrawal require(amount != 0, "withdraw: order has no positive value"); require(order.withdrawn == false, "withdraw: this order Id has been already withdrawn or waiting for the swap"); _withdrawOrderBalance(orderId, _msgSender()); if (asset == _ethAssetIdentificator) { _msgSender().transfer(amount); } else { IERC20(asset).safeTransfer(_msgSender(), amount); } emit AssetWithdrawal(orderId, _msgSender(), asset, amount); } function _activateIfUserIsNew( address user ) internal returns (bool) { if (_doesUserExist(user) == false) { _users[user].exist = true; _usersById[_usersCount] = user; _usersCount++; } return true; } function _depositOrderBalance( uint256 orderId, address user, address asset, uint256 amount ) internal returns (bool) { _users[user].orderIdByIndex[_users[user].index] = orderId; _users[user].orders[orderId] = OrderDetails(true, asset, amount, false, block.timestamp); return true; } function _reopenExistingOrder( uint256 orderId, address user ) internal returns (bool) { _users[user].orders[orderId].withdrawn = false; _users[user].orders[orderId].initTimestamp = block.timestamp; return true; } function _withdrawOrderBalance( uint256 orderId, address user ) internal returns (bool) { _users[user].orders[orderId].withdrawn = true; return true; } function _doesUserExist( address user ) internal view returns (bool) { return _users[user].exist; } function _getOrderDetails( uint256 orderId, address user ) internal view returns (OrderDetails memory order) { return _users[user].orders[orderId]; } } /** * @title CrossBlockchainSwap * @dev Fully autonomous cross-blockchain swapping smart contract */ contract CrossBlockchainSwap is AssetsValue { // ----------------------------------------- // EVENTS // ----------------------------------------- event Initiated( uint256 indexed orderId, bytes32 indexed secretHash, address indexed initiator, address recipient, uint256 initTimestamp, uint256 refundTimestamp, address asset, uint256 amount ); event Redeemed( bytes32 secretHash, uint256 redeemTimestamp, bytes32 secret, address indexed redeemer ); event Refunded( uint256 orderId, bytes32 secretHash, uint256 refundTime, address indexed refunder ); // ----------------------------------------- // MODIFIERS // ----------------------------------------- modifier swapIsNotInitiated(bytes32 secretHash) { require(_swaps[secretHash].state == State.Empty, "swapIsNotInitiated: this secret hash was already used, please use another one"); _; } modifier swapIsRedeemable(bytes32 secret) { bool isRedeemable = _isRedeemable(secret); require(isRedeemable, "swapIsRedeemable: the redeem is not available"); _; } modifier swapIsRefundable(bytes32 secretHash, address refunder) { bool isRefundable = _isRefundable(secretHash, refunder); require(isRefundable, "swapIsRefundable: refund is not available"); _; } // ----------------------------------------- // EXTERNAL // ----------------------------------------- /** * @dev If user wants to swap ERC token, before initiating the swap between that * initiator need to call approve method from his tokens' smart contract, * approving to it to spend the value1 amount of tokens * @param secretHash the encoded secret which they discussed at offline (SHA256) * @param refundTimestamp the period when the swap should be active * it should be written in MINUTES */ function initiate( uint256 orderId, bytes32 secretHash, address recipient, uint256 refundTimestamp ) public swapIsNotInitiated(secretHash) { require(recipient != address(0), "initiate: invalid recipient address"); // validation that refund Timestamp more than exchange min limit and less then max limit _validateRefundTimestamp(refundTimestamp * 1 minutes); OrderDetails memory order = _getOrderDetails(orderId, _msgSender()); // validation of the deposited order existing and non-zero amount require(order.created == true, "initiate: this order Id has not been created and deposited yet"); require(order.withdrawn == false, "initiate: this order deposit has been withdrawn"); require(order.amount != 0, "initiate: this order Id has been withdrawn, finished or waiting for the redeem"); // withdrawing the balance of this orderId from sender deposites _withdrawOrderBalance(orderId, _msgSender()); // swap asset details _swaps[secretHash].asset = order.asset; _swaps[secretHash].amount = order.amount; // swap status _swaps[secretHash].state = State.Filled; // swap clients _swaps[secretHash].initiator = _msgSender(); _swaps[secretHash].recipient = recipient; _swaps[secretHash].secretHash = secretHash; _swaps[secretHash].orderId = orderId; // swap timestapms _swaps[secretHash].initTimestamp = block.timestamp; _swaps[secretHash].refundTimestamp = block.timestamp + (refundTimestamp * 1 minutes); // updating the initiator state Initiator storage initiator = _initiators[_msgSender()]; initiator.swaps[initiator.index] = secretHash; initiator.index++; initiator.filledSwaps++; // Update deposits mapping and count _swapsById[_swapsCount] = secretHash; _swapsCount++; emit Initiated( orderId, secretHash, _msgSender(), recipient, block.timestamp, refundTimestamp, order.asset, order.amount ); } /** * @dev The participant of swap, who has the secret word and the secret hash can call this method * and receive assets from contract. * @param secret which both sides discussed before initialization */ function redeem( bytes32 secret ) external swapIsRedeemable(secret) { // storing the secret hash generated from secret bytes32 secretHash = _hashTheSecret(secret); // closing the state of this swap order _swaps[secretHash].state = State.Redeemed; // storing the recipient address address recipient = _swaps[secretHash].recipient; if (_getSwapAssetType(secretHash) == SwapType.ETH) { // converting recipient address to payable address address payable payableReceiver = address(uint160(recipient)); // transfer ETH to recipient wallet payableReceiver.transfer(_swaps[secretHash].amount); } else { // transfer tokens to recipient address IERC20(_swaps[secretHash].asset).safeTransfer(recipient, _swaps[secretHash].amount); } // saving the secret _swaps[secretHash].secret = secret; // decrease the filled swaps amount _initiators[_swaps[secretHash].initiator].filledSwaps--; emit Redeemed ( secretHash, block.timestamp, secret, recipient ); } /** * @dev The initiator can get back his tokens until refundTimestamp comes, * after that both sides cannot do anything with this swap * @param secretHash the encoded secret which they discussed at offline (SHA256) */ function refund( bytes32 secretHash ) public swapIsRefundable(secretHash, _msgSender()) { _swaps[secretHash].state = State.Refunded; _reopenExistingOrder(_swaps[secretHash].orderId,_msgSender()); // decrease the filled swapss amount _initiators[_msgSender()].filledSwaps--; emit Refunded( _swaps[secretHash].orderId, secretHash, block.timestamp, _msgSender() ); } /** * @dev The method do 2 actions and optimize the processes * It call refund and withdraw * @param secretHash the encoded secret which they discussed at offline (SHA256) */ function refundAndWithdraw( bytes32 secretHash ) external { refund(secretHash); uint256 orderId = _swaps[secretHash].orderId; _withdraw(orderId); } /** * @dev The method do the same think as refundAndWithdraw, but for all expired swaps * The caller should be able to refund and withdraw all own swaps and deposits */ function refundAndWithdrawAll() external { uint256 filledSwaps = _initiators[_msgSender()].filledSwaps; for (uint256 i = 0; i < filledSwaps; i++) { bytes32 secretHash = _swaps[_initiators[_msgSender()].swaps[i]].secretHash; if (_isRefundable(secretHash, _msgSender())) { uint256 orderId = _swaps[_initiators[_msgSender()].swaps[i]].orderId; refund(secretHash); _withdraw(orderId); } } } // ----------------------------------------- // GETTERS // ----------------------------------------- /** * @dev Method returns all atomic swaps for specified user with optional state filter. * @param initiator the address of user * @param state of required swap, represented as a Enum type with 4 options (0 - 3) * @return orderIds array of order ids with required state */ function getUserSwapsByState( address initiator, State state, uint256 cursor, uint256 howMany ) public view returns ( uint256[] memory orderIds, uint256 newCursor ) { uint256 swapsLength = _initiators[initiator].index; uint256 filteredOrdersLength = 0; // calculate lenght of necesseary array for (uint256 i = 0; i < swapsLength; i++){ Swap memory swap = _swaps[_initiators[initiator].swaps[i]]; if (swap.state == state) { filteredOrdersLength++; } } uint256 length = howMany; if (length > filteredOrdersLength - cursor) { length = filteredOrdersLength - cursor; } // create new array with necesseary array lengths orderIds = new uint256[](length); // filter orderIds by requirement uint256 j = 0; for (uint256 i = 0; i < swapsLength; i++){ if (j == length) { break; } else { Swap memory swap = _swaps[_initiators[initiator].swaps[cursor + i]]; if (swap.state == state) { orderIds[j] = swap.orderId; j++; } } } return ( orderIds, cursor + length ); } /** * @dev Get user filled swaps count * @return uint256 count */ function getUserFilledOrdersCount( address user ) external view returns ( uint256 count ) { return _initiators[user].filledSwaps; } /** * @dev Get filled swaps order ids and amounts * @return uint256[] of order ids * @return uint256[] of amounts * @return uint256[] of creation id's */ function getUserFilledOrders( address user, uint256 cursor, uint256 howMany ) external view returns ( uint256[] memory orderIds, uint256[] memory amounts, uint256[] memory initTimestamps, uint256 newCursor ) { uint256 filledSwaps = _initiators[user].filledSwaps; uint256 length = howMany; if (length > filledSwaps - cursor) { length = filledSwaps - cursor; } orderIds = new uint256[](length); amounts = new uint256[](length); initTimestamps = new uint256[](length); uint256 j = 0; for(uint256 i = 0; i <= _initiators[user].index; i++){ if (j == length) { break; } else { Swap memory swap = _swaps[_initiators[user].swaps[cursor + i]]; if (swap.state == State.Filled) { amounts[j] = swap.amount; orderIds[j] = swap.orderId; initTimestamps[j] = swap.initTimestamp; j++; } } } return ( orderIds, amounts, initTimestamps, cursor + length ); } /** * @dev Identification of the swap type with assets and value fields * @param secretHash the encoded secret which they discussed at offline (SHA256) * @return tp (type) of swap */ function getSwapAssetType( bytes32 secretHash ) public view returns (SwapType tp) { return _getSwapAssetType(secretHash); } /** * @dev Check the secret hash for existence, it can be used in UI for form validation * @param secretHash the encoded secret which they discussed at offline (SHA256) * @return state of this swap */ function getSwapData( bytes32 _secretHash ) external view returns ( uint256 initTimestamp, uint256 refundTimestamp, bytes32 secretHash, bytes32 secret, address initiator, address recipient, address asset, uint256 amount, State state ) { Swap memory swap = _swaps[_secretHash]; return ( swap.initTimestamp, swap.refundTimestamp, swap.secretHash, swap.secret, swap.initiator, swap.recipient, swap.asset, swap.amount, swap.state ); } /** * @dev Method check and return array of orderIds, which can being refunded by provided user * @param user address of user * @return array of uint256 orderIds */ function getExpiredSwaps( address user ) public view returns ( uint256[] memory orderIds, bytes32[] memory secretHashes ) { uint256 swapsLength = _initiators[user].index; uint256 expiredSwapsLength = 0; // calculate lenght of refund timestamps array for (uint256 i = 0; i < swapsLength; i++){ bytes32 secretHash = _initiators[user].swaps[i]; Swap memory swap = _swaps[secretHash]; if (block.timestamp >= swap.refundTimestamp && swap.state == State.Filled) { expiredSwapsLength++; } } // create new array with necesseary array lengths orderIds = new uint256[](expiredSwapsLength); secretHashes = new bytes32[](expiredSwapsLength); // filter orderIds by refund timestamp uint256 j = 0; for (uint256 i = 0; i < swapsLength; i++){ bytes32 secretHash = _initiators[user].swaps[i]; Swap memory swap = _swaps[secretHash]; if (block.timestamp >= swap.refundTimestamp && swap.state == State.Filled) { orderIds[j] = swap.orderId; secretHashes[j] = secretHash; j++; } } return ( orderIds, secretHashes ); } /** * @dev To avoid issues between solidity hashing algorithm and the algorithm which will be used in the platform * we gonna use the same hashing algorithm which uses the smart contract * this is only the getter method without interaction from the blockchain, so it is safe * @return secret hash of bytes32 secret */ function getHashOfSecret( bytes32 secret ) external pure returns (bytes32) { return _hashTheSecret(secret); } /** * @dev Get limits of a lifetime for swap in minutes * @return min lifetime * @return max lifetime */ function getSwapLifetimeLimits() public view returns ( uint256 min, uint256 max ) { return ( _swapTimeLimits.min, _swapTimeLimits.max ); } /** * @dev Get the count of initiated swaps */ function getSwapsCount() external view returns ( uint256 swapsCount ) { return _swapsCount; } /** * @dev Get the secretHash by provided id */ function getSwapsSecretHashById( uint256 swapId ) external view returns ( bytes32 secretHash ) { return _swapsById[swapId]; } // ----------------------------------------- // INTERNAL // ----------------------------------------- /** * @dev Validating the period time of swap * It should be equal/bigger than 10 minutes and equal/less than 180 days */ function _validateRefundTimestamp( uint256 refundTimestamp ) private view { require(refundTimestamp >= _swapTimeLimits.min, "_validateRefundTimestamp: the timestamp should be bigger than min swap lifetime"); require(_swapTimeLimits.max >= refundTimestamp, "_validateRefundTimestamp: the timestamp should be smaller than max swap lifetime"); } function _isRefundable( bytes32 secretHash, address refunder ) internal view returns (bool) { bool isFilled = _swaps[secretHash].state == State.Filled; bool isCallerInitiator = _swaps[secretHash].initiator == refunder; uint256 refundTimestamp = _swaps[secretHash].refundTimestamp; bool isTimeReached = block.timestamp >= refundTimestamp; return isFilled && isCallerInitiator && isTimeReached; } function _isRedeemable( bytes32 secret ) internal view returns (bool) { bytes32 secretHash = _hashTheSecret(secret); bool isSwapFilled = _swaps[secretHash].state == State.Filled; uint256 refundTimestamp = _swaps[secretHash].refundTimestamp; bool isSwapActive = refundTimestamp > block.timestamp; return isSwapFilled && isSwapActive; } function _hashTheSecret( bytes32 secret ) private pure returns (bytes32) { return sha256(abi.encodePacked(secret)); } function _getSwapAssetType( bytes32 secretHash ) private view returns (SwapType tp) { if (_swaps[secretHash].asset == _ethAssetIdentificator) { return SwapType.ETH; } else { return SwapType.Token; } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_logic","type":"address"},{"internalType":"address","name":"_admin","type":"address"}],"payable":true,"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newMin","type":"uint256"},{"internalType":"uint256","name":"newMax","type":"uint256"}],"name":"changeSwapLifetimeLimits","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"string","name":"newVersion","type":"string"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"string","name":"newVersion","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
600480546001600160a01b031916905560c06040819052610258608081905262ed4e0060a0819052600b91909155600c5562000fd038819003908190833981810160405260408110156200005257600080fd5b508051602090910151816200006f6001600160e01b036200019716565b600080546001600160a01b0319166001600160a01b03928316178082556040519216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a360405180602362000f72823960405190819003602301902060008051602062000f52833981519152149050620000e957fe5b62000130816040518060400160405280600581526020017f312e302e300000000000000000000000000000000000000000000000000000008152506200019c60201b60201c565b50604080517f6f72672e7a657070656c696e6f732e70726f78792e61646d696e0000000000008152905190819003601a01902060008051602062000f32833981519152146200017b57fe5b6200018f816001600160e01b036200023c16565b5050620002f7565b335b90565b620001bb826001600160a01b03166200024f60201b62000a311760201c565b62000212576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b81526020018062000f95603b913960400191505060405180910390fd5b80516200022790600d90602084019062000255565b505060008051602062000f5283398151915255565b60008051602062000f3283398151915255565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200029857805160ff1916838001178555620002c8565b82800160010185558215620002c8579182015b82811115620002c8578251825591602001919060010190620002ab565b50620002d6929150620002da565b5090565b6200019991905b80821115620002d65760008155600101620002e1565b610c2b80620003076000396000f3fe60806040526004361061009c5760003560e01c80638f283970116100645780638f283970146102185780638f32d59b1461024b578063a4cdbd1414610274578063d7e24337146102a4578063f2fde38b14610376578063f851a440146103a95761009c565b806336ba9794146100a657806354fd4d50146101335780635c60da1b146101bd578063715018a6146101ee5780638da5cb5b14610203575b6100a46103be565b005b3480156100b257600080fd5b506100a4600480360360408110156100c957600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100f457600080fd5b82018360208201111561010657600080fd5b8035906020019184600183028401116401000000008311171561012857600080fd5b5090925090506103d8565b34801561013f57600080fd5b5061014861044b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561018257818101518382015260200161016a565b50505050905090810190601f1680156101af5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101c957600080fd5b506101d26104e2565b604080516001600160a01b039092168252519081900360200190f35b3480156101fa57600080fd5b506100a46104f1565b34801561020f57600080fd5b506101d261054c565b34801561022457600080fd5b506100a46004803603602081101561023b57600080fd5b50356001600160a01b031661055b565b34801561025757600080fd5b50610260610625565b604080519115158252519081900360200190f35b34801561028057600080fd5b506100a46004803603604081101561029757600080fd5b5080359060200135610649565b6100a4600480360360608110156102ba57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156102e557600080fd5b8201836020820111156102f757600080fd5b8035906020019184600183028401116401000000008311171561031957600080fd5b91939092909160208101903564010000000081111561033757600080fd5b82018360208201111561034957600080fd5b8035906020019184600183028401116401000000008311171561036b57600080fd5b5090925090506106fb565b34801561038257600080fd5b506100a46004803603602081101561039957600080fd5b50356001600160a01b03166107e1565b3480156103b557600080fd5b506101d26107fb565b6103c6610805565b6103d66103d1610865565b61088a565b565b6103e06108ae565b6001600160a01b0316336001600160a01b0316141561043e576104398383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506108d392505050565b610446565b6104466103be565b505050565b600d8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104d75780601f106104ac576101008083540402835291602001916104d7565b820191906000526020600020905b8154815290600101906020018083116104ba57829003601f168201915b505050505090505b90565b60006104ec610865565b905090565b6104f9610625565b61050257600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6105636108ae565b6001600160a01b0316336001600160a01b0316141561061a576001600160a01b0381166105c15760405162461bcd60e51b8152600401808060200182810382526036815260200180610b026036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6105ea6108ae565b604080516001600160a01b03928316815291841660208301528051918290030190a161061581610915565b610622565b6106226103be565b50565b600080546001600160a01b031661063a610939565b6001600160a01b031614905090565b610651610625565b61065a57600080fd5b816106965760405162461bcd60e51b8152600401808060200182810382526043815260200180610b386043913960600191505060405180910390fd5b818110156106d55760405162461bcd60e51b8152600401808060200182810382526041815260200180610bb66041913960600191505060405180910390fd5b60408051808201909152603c928302808252919092026020909201829052600b55600c55565b6107036108ae565b6001600160a01b0316336001600160a01b031614156107d25761075c8585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506108d392505050565b6000856001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d80600081146107b9576040519150601f19603f3d011682016040523d82523d6000602084013e6107be565b606091505b50509050806107cc57600080fd5b506107da565b6107da6103be565b5050505050565b6107e9610625565b6107f257600080fd5b6106228161093d565b60006104ec6108ae565b61080d6108ae565b6001600160a01b0316336001600160a01b0316141561085d5760405162461bcd60e51b8152600401808060200182810382526032815260200180610ad06032913960400191505060405180910390fd5b6103d66103d6565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e8080156108a9573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b6108dd82826109ab565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b3390565b6001600160a01b03811661095057600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6109bd826001600160a01b0316610a31565b6109f85760405162461bcd60e51b815260040180806020018281038252603b815260200180610b7b603b913960400191505060405180910390fd5b8051610a0b90600d906020840190610a37565b50507f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610a7857805160ff1916838001178555610aa5565b82800160010185558215610aa5579182015b82811115610aa5578251825591602001919060010190610a8a565b50610ab1929150610ab5565b5090565b6104df91905b80821115610ab15760008155600101610abb56fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f20616464726573736368616e6765537761704c69666574696d654c696d6974733a206e65774d696e20616e64206e65774d61782073686f756c6420626520626967676572207468656e203043616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e747261637420616464726573736368616e6765537761704c69666574696d654c696d6974733a20746865206e65774d61782073686f756c6420626520626967676572207468656e206e65774d6178a265627a7a72315820843eae6f470e00ecfd07082b9bfe0eb5c50392ea0845c59834fcb048d3306ca064736f6c634300050c003210d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c36f72672e7a657070656c696e6f732e70726f78792e696d706c656d656e746174696f6e43616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373000000000000000000000000c6304e326b2462f59d811285eab0d5a50266f362000000000000000000000000fc93512d1848fa37f40d7782ffc291617c0e5615
Deployed Bytecode
0x60806040526004361061009c5760003560e01c80638f283970116100645780638f283970146102185780638f32d59b1461024b578063a4cdbd1414610274578063d7e24337146102a4578063f2fde38b14610376578063f851a440146103a95761009c565b806336ba9794146100a657806354fd4d50146101335780635c60da1b146101bd578063715018a6146101ee5780638da5cb5b14610203575b6100a46103be565b005b3480156100b257600080fd5b506100a4600480360360408110156100c957600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156100f457600080fd5b82018360208201111561010657600080fd5b8035906020019184600183028401116401000000008311171561012857600080fd5b5090925090506103d8565b34801561013f57600080fd5b5061014861044b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561018257818101518382015260200161016a565b50505050905090810190601f1680156101af5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101c957600080fd5b506101d26104e2565b604080516001600160a01b039092168252519081900360200190f35b3480156101fa57600080fd5b506100a46104f1565b34801561020f57600080fd5b506101d261054c565b34801561022457600080fd5b506100a46004803603602081101561023b57600080fd5b50356001600160a01b031661055b565b34801561025757600080fd5b50610260610625565b604080519115158252519081900360200190f35b34801561028057600080fd5b506100a46004803603604081101561029757600080fd5b5080359060200135610649565b6100a4600480360360608110156102ba57600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156102e557600080fd5b8201836020820111156102f757600080fd5b8035906020019184600183028401116401000000008311171561031957600080fd5b91939092909160208101903564010000000081111561033757600080fd5b82018360208201111561034957600080fd5b8035906020019184600183028401116401000000008311171561036b57600080fd5b5090925090506106fb565b34801561038257600080fd5b506100a46004803603602081101561039957600080fd5b50356001600160a01b03166107e1565b3480156103b557600080fd5b506101d26107fb565b6103c6610805565b6103d66103d1610865565b61088a565b565b6103e06108ae565b6001600160a01b0316336001600160a01b0316141561043e576104398383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506108d392505050565b610446565b6104466103be565b505050565b600d8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104d75780601f106104ac576101008083540402835291602001916104d7565b820191906000526020600020905b8154815290600101906020018083116104ba57829003601f168201915b505050505090505b90565b60006104ec610865565b905090565b6104f9610625565b61050257600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6105636108ae565b6001600160a01b0316336001600160a01b0316141561061a576001600160a01b0381166105c15760405162461bcd60e51b8152600401808060200182810382526036815260200180610b026036913960400191505060405180910390fd5b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6105ea6108ae565b604080516001600160a01b03928316815291841660208301528051918290030190a161061581610915565b610622565b6106226103be565b50565b600080546001600160a01b031661063a610939565b6001600160a01b031614905090565b610651610625565b61065a57600080fd5b816106965760405162461bcd60e51b8152600401808060200182810382526043815260200180610b386043913960600191505060405180910390fd5b818110156106d55760405162461bcd60e51b8152600401808060200182810382526041815260200180610bb66041913960600191505060405180910390fd5b60408051808201909152603c928302808252919092026020909201829052600b55600c55565b6107036108ae565b6001600160a01b0316336001600160a01b031614156107d25761075c8585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506108d392505050565b6000856001600160a01b031683836040518083838082843760405192019450600093509091505080830381855af49150503d80600081146107b9576040519150601f19603f3d011682016040523d82523d6000602084013e6107be565b606091505b50509050806107cc57600080fd5b506107da565b6107da6103be565b5050505050565b6107e9610625565b6107f257600080fd5b6106228161093d565b60006104ec6108ae565b61080d6108ae565b6001600160a01b0316336001600160a01b0316141561085d5760405162461bcd60e51b8152600401808060200182810382526032815260200180610ad06032913960400191505060405180910390fd5b6103d66103d6565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e8080156108a9573d6000f35b3d6000fd5b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b5490565b6108dd82826109ab565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a25050565b7f10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b55565b3390565b6001600160a01b03811661095057600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6109bd826001600160a01b0316610a31565b6109f85760405162461bcd60e51b815260040180806020018281038252603b815260200180610b7b603b913960400191505060405180910390fd5b8051610a0b90600d906020840190610a37565b50507f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c355565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610a7857805160ff1916838001178555610aa5565b82800160010185558215610aa5579182015b82811115610aa5578251825591602001919060010190610a8a565b50610ab1929150610ab5565b5090565b6104df91905b80821115610ab15760008155600101610abb56fe43616e6e6f742063616c6c2066616c6c6261636b2066756e6374696f6e2066726f6d207468652070726f78792061646d696e43616e6e6f74206368616e6765207468652061646d696e206f6620612070726f787920746f20746865207a65726f20616464726573736368616e6765537761704c69666574696d654c696d6974733a206e65774d696e20616e64206e65774d61782073686f756c6420626520626967676572207468656e203043616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e747261637420616464726573736368616e6765537761704c69666574696d654c696d6974733a20746865206e65774d61782073686f756c6420626520626967676572207468656e206e65774d6178a265627a7a72315820843eae6f470e00ecfd07082b9bfe0eb5c50392ea0845c59834fcb048d3306ca064736f6c634300050c0032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c6304e326b2462f59d811285eab0d5a50266f362000000000000000000000000fc93512d1848fa37f40d7782ffc291617c0e5615
-----Decoded View---------------
Arg [0] : _logic (address): 0xC6304e326B2462f59D811285EaB0d5a50266f362
Arg [1] : _admin (address): 0xFc93512D1848fA37F40D7782ffC291617c0e5615
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000c6304e326b2462f59d811285eab0d5a50266f362
Arg [1] : 000000000000000000000000fc93512d1848fa37f40d7782ffc291617c0e5615
Deployed Bytecode Sourcemap
22757:426:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14516:11;:9;:11::i;:::-;22757:426;20952:142;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20952:142:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;20952:142:0;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;20952:142:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;20952:142:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;20952:142:0;;-1:-1:-1;20952:142:0;-1:-1:-1;20952:142:0;:::i;20086:82::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20086:82:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;20086:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20233:92;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20233:92:0;;;:::i;:::-;;;;-1:-1:-1;;;;;20233:92:0;;;;;;;;;;;;;;9520:140;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9520:140:0;;;:::i;8728:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8728:79:0;;;:::i;20502:221::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20502:221:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20502:221:0;-1:-1:-1;;;;;20502:221:0;;:::i;9063:94::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9063:94:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;13647:410;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13647:410:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13647:410:0;;;;;;;:::i;21656:258::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;21656:258:0;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;21656:258:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;21656:258:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;21656:258:0;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;21656:258:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;21656:258:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;21656:258:0;;-1:-1:-1;21656:258:0;-1:-1:-1;21656:258:0;:::i;9837:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9837:109:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9837:109:0;-1:-1:-1;;;;;9837:109:0;;:::i;19952:74::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19952:74:0;;;:::i;14628:88::-;14663:15;:13;:15::i;:::-;14683:28;14693:17;:15;:17::i;:::-;14683:9;:28::i;:::-;14628:88::o;20952:142::-;19828:8;:6;:8::i;:::-;-1:-1:-1;;;;;19814:22:0;:10;-1:-1:-1;;;;;19814:22:0;;19810:76;;;21048:41;21059:17;21078:10;;21048:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;21048:10:0;;-1:-1:-1;;;21048:41:0:i;:::-;19810:76;;;19869:11;:9;:11::i;:::-;20952:142;;;:::o;20086:82::-;20155:8;20148:15;;;;;;;;-1:-1:-1;;20148:15:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20128:13;;20148:15;;20155:8;;20148:15;;20155:8;20148:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20086:82;;:::o;20233:92::-;20282:7;20303:17;:15;:17::i;:::-;20296:24;;20233:92;:::o;9520:140::-;8940:9;:7;:9::i;:::-;8932:18;;;;;;9619:1;9603:6;;9582:40;;-1:-1:-1;;;;;9603:6:0;;;;9582:40;;9619:1;;9582:40;9650:1;9633:19;;-1:-1:-1;;;;;;9633:19:0;;;9520:140::o;8728:79::-;8766:7;8793:6;-1:-1:-1;;;;;8793:6:0;8728:79;:::o;20502:221::-;19828:8;:6;:8::i;:::-;-1:-1:-1;;;;;19814:22:0;:10;-1:-1:-1;;;;;19814:22:0;;19810:76;;;-1:-1:-1;;;;;20571:22:0;;20563:89;;;;-1:-1:-1;;;20563:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20662:32;20675:8;:6;:8::i;:::-;20662:32;;;-1:-1:-1;;;;;20662:32:0;;;;;;;;;;;;;;;;;;;;;20699:19;20709:8;20699:9;:19::i;:::-;19810:76;;;19869:11;:9;:11::i;:::-;20502:221;:::o;9063:94::-;9103:4;9143:6;;-1:-1:-1;;;;;9143:6:0;9127:12;:10;:12::i;:::-;-1:-1:-1;;;;;9127:22:0;;9120:29;;9063:94;:::o;13647:410::-;8940:9;:7;:9::i;:::-;8932:18;;;;;;13776:11;13768:91;;;;-1:-1:-1;;;13768:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13888:6;13878;:16;;13870:94;;;;-1:-1:-1;;;13870:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13995:54;;;;;;;;;14019:9;14010:18;;;13995:54;;;14030:18;;;;13995:54;;;;;;;13977:15;:72;;;13647:410::o;21656:258::-;19828:8;:6;:8::i;:::-;-1:-1:-1;;;;;19814:22:0;:10;-1:-1:-1;;;;;19814:22:0;;19810:76;;;21788:41;21799:17;21818:10;;21788:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;21788:10:0;;-1:-1:-1;;;21788:41:0:i;:::-;21835:12;21852:17;-1:-1:-1;;;;;21852:30:0;21883:4;;21852:36;;;;;30:3:-1;22:6;14;1:33;21852:36:0;;45:16:-1;;;-1:-1;21852:36:0;;-1:-1:-1;21852:36:0;;-1:-1:-1;;21852:36:0;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;21834:54:0;;;21901:7;21893:16;;;;;;19847:1;19810:76;;;19869:11;:9;:11::i;:::-;21656:258;;;;;:::o;9837:109::-;8940:9;:7;:9::i;:::-;8932:18;;;;;;9910:28;9929:8;9910:18;:28::i;19952:74::-;19992:7;20013:8;:6;:8::i;22416:155::-;22477:8;:6;:8::i;:::-;-1:-1:-1;;;;;22463:22:0;:10;-1:-1:-1;;;;;22463:22:0;;;22455:85;;;;-1:-1:-1;;;22455:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22545:21;:19;:21::i;17098:154::-;16736:66;17232:11;;17215:33::o;15249:708::-;15542:12;15539:1;15536;15523:32;15727:1;15724;15710:12;15707:1;15691:14;15686:3;15673:56;15788:14;15785:1;15782;15767:36;15817:6;15868:36;;;;15929:14;15926:1;15919:25;15868:36;15887:14;15884:1;15877:25;21960:134;19527:66;22074:11;;22058:32::o;17432:180::-;17519:49;17538:17;17557:10;17519:18;:49::i;:::-;17580:27;;-1:-1:-1;;;;;17580:27:0;;;;;;;;17432:180;;:::o;22211:129::-;19527:66;22309:22;22303:33::o;3793:98::-;3873:10;3793:98;:::o;10096:187::-;-1:-1:-1;;;;;10170:22:0;;10162:31;;;;;;10230:6;;;10209:38;;-1:-1:-1;;;;;10209:38:0;;;;10230:6;;;10209:38;;;10258:6;:17;;-1:-1:-1;;;;;;10258:17:0;-1:-1:-1;;;;;10258:17:0;;;;;;;;;;10096:187::o;17794:332::-;17897:30;:17;-1:-1:-1;;;;;17897:28:0;;:30::i;:::-;17889:102;;;;-1:-1:-1;;;17889:102:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17999:21;;;;:8;;:21;;;;;:::i;:::-;-1:-1:-1;;16736:66:0;18086:31;18077:45::o;2379:627::-;2951:20;2990:8;;;2379:627::o;22757:426::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22757:426:0;;;-1:-1:-1;22757:426:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;
Swarm Source
bzzr://843eae6f470e00ecfd07082b9bfe0eb5c50392ea0845c59834fcb048d3306ca0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.