Feature Tip: Add private address tag to any address under My Name Tag !
Latest 25 from a total of 250,889 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Approve | 24508586 | 6 hrs ago | IN | 0 ETH | 0.000006 | ||||
| Transfer | 24508498 | 6 hrs ago | IN | 0 ETH | 0.00000264 | ||||
| Approve | 24508306 | 7 hrs ago | IN | 0 ETH | 0.00006725 | ||||
| Approve | 24508298 | 7 hrs ago | IN | 0 ETH | 0.00006728 | ||||
| Transfer | 24505095 | 18 hrs ago | IN | 0 ETH | 0.00010301 | ||||
| Approve | 24504624 | 19 hrs ago | IN | 0 ETH | 0.00000394 | ||||
| Transfer | 24503172 | 24 hrs ago | IN | 0 ETH | 0.00000355 | ||||
| Approve | 24503037 | 25 hrs ago | IN | 0 ETH | 0.0000021 | ||||
| Approve | 24502702 | 26 hrs ago | IN | 0 ETH | 0.00000322 | ||||
| Transfer | 24501473 | 30 hrs ago | IN | 0 ETH | 0.00000956 | ||||
| Approve | 24501448 | 30 hrs ago | IN | 0 ETH | 0.00002897 | ||||
| Transfer | 24501328 | 30 hrs ago | IN | 0 ETH | 0.00000319 | ||||
| Approve | 24500961 | 32 hrs ago | IN | 0 ETH | 0.00000522 | ||||
| Transfer | 24500616 | 33 hrs ago | IN | 0 ETH | 0.00013638 | ||||
| Transfer | 24500349 | 34 hrs ago | IN | 0 ETH | 0.00000266 | ||||
| Transfer | 24499793 | 36 hrs ago | IN | 0 ETH | 0.00000633 | ||||
| Transfer | 24499774 | 36 hrs ago | IN | 0 ETH | 0.00000645 | ||||
| Transfer | 24496810 | 46 hrs ago | IN | 0 ETH | 0.00000942 | ||||
| Transfer | 24496108 | 2 days ago | IN | 0 ETH | 0.00000441 | ||||
| Transfer | 24496100 | 2 days ago | IN | 0 ETH | 0.00000311 | ||||
| Approve | 24495853 | 2 days ago | IN | 0 ETH | 0.00012953 | ||||
| Transfer | 24495844 | 2 days ago | IN | 0 ETH | 0.00015033 | ||||
| Transfer | 24494852 | 2 days ago | IN | 0 ETH | 0.00000367 | ||||
| Transfer | 24494148 | 2 days ago | IN | 0 ETH | 0.00000233 | ||||
| Approve | 24492059 | 2 days ago | IN | 0 ETH | 0.00001869 |
Latest 18 internal transactions
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 19812777 | 656 days ago | 0.00650245 ETH | ||||
| Transfer | 19804036 | 657 days ago | 0.01276057 ETH | ||||
| Transfer | 19803976 | 657 days ago | 0.01593737 ETH | ||||
| Transfer | 19803863 | 657 days ago | 0.01595869 ETH | ||||
| Transfer | 19800060 | 658 days ago | 0.0064145 ETH | ||||
| Transfer | 19798814 | 658 days ago | 0.00960941 ETH | ||||
| Transfer | 19798624 | 658 days ago | 0.00639343 ETH | ||||
| Transfer | 19798485 | 658 days ago | 0.00264955 ETH | ||||
| Transfer | 19798410 | 658 days ago | 0.00096146 ETH | ||||
| Transfer | 19798335 | 658 days ago | 0.00224032 ETH | ||||
| Transfer | 19792875 | 659 days ago | 0.00224919 ETH | ||||
| Transfer | 19791196 | 659 days ago | 0.00162116 ETH | ||||
| Transfer | 19791151 | 659 days ago | 0.00259893 ETH | ||||
| Transfer | 19769332 | 662 days ago | 0.00168834 ETH | ||||
| Transfer | 19763544 | 663 days ago | 0.00157433 ETH | ||||
| Transfer | 19762493 | 663 days ago | 0.00157649 ETH | ||||
| Transfer | 19762429 | 663 days ago | 0.00158038 ETH | ||||
| Transfer | 15226677 | 1305 days ago | 0.001 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ERC20Proxy
Compiler Version
v0.4.21+commit.dfe3193c
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2018-09-10
*/
pragma solidity ^0.4.21;
/** @title A contract for generating unique identifiers
*
* @notice A contract that provides a identifier generation scheme,
* guaranteeing uniqueness across all contracts that inherit from it,
* as well as unpredictability of future identifiers.
*
* @dev This contract is intended to be inherited by any contract that
* implements the callback software pattern for cooperative custodianship.
*
* @author Gemini Trust Company, LLC
*/
contract LockRequestable {
// MEMBERS
/// @notice the count of all invocations of `generateLockId`.
uint256 public lockRequestCount;
// CONSTRUCTOR
function LockRequestable() public {
lockRequestCount = 0;
}
// FUNCTIONS
/** @notice Returns a fresh unique identifier.
*
* @dev the generation scheme uses three components.
* First, the blockhash of the previous block.
* Second, the deployed address.
* Third, the next value of the counter.
* This ensure that identifiers are unique across all contracts
* following this scheme, and that future identifiers are
* unpredictable.
*
* @return a 32-byte unique identifier.
*/
function generateLockId() internal returns (bytes32 lockId) {
return keccak256(block.blockhash(block.number - 1), address(this), ++lockRequestCount);
}
}
/** @title A contract to inherit upgradeable custodianship.
*
* @notice A contract that provides re-usable code for upgradeable
* custodianship. That custodian may be an account or another contract.
*
* @dev This contract is intended to be inherited by any contract
* requiring a custodian to control some aspect of its functionality.
* This contract provides the mechanism for that custodianship to be
* passed from one custodian to the next.
*
* @author Gemini Trust Company, LLC
*/
contract CustodianUpgradeable is LockRequestable {
// TYPES
/// @dev The struct type for pending custodian changes.
struct CustodianChangeRequest {
address proposedNew;
}
// MEMBERS
/// @dev The address of the account or contract that acts as the custodian.
address public custodian;
/// @dev The map of lock ids to pending custodian changes.
mapping (bytes32 => CustodianChangeRequest) public custodianChangeReqs;
// CONSTRUCTOR
function CustodianUpgradeable(
address _custodian
)
LockRequestable()
public
{
custodian = _custodian;
}
// MODIFIERS
modifier onlyCustodian {
require(msg.sender == custodian);
_;
}
// PUBLIC FUNCTIONS
// (UPGRADE)
/** @notice Requests a change of the custodian associated with this contract.
*
* @dev Returns a unique lock id associated with the request.
* Anyone can call this function, but confirming the request is authorized
* by the custodian.
*
* @param _proposedCustodian The address of the new custodian.
* @return lockId A unique identifier for this request.
*/
function requestCustodianChange(address _proposedCustodian) public returns (bytes32 lockId) {
require(_proposedCustodian != address(0));
lockId = generateLockId();
custodianChangeReqs[lockId] = CustodianChangeRequest({
proposedNew: _proposedCustodian
});
emit CustodianChangeRequested(lockId, msg.sender, _proposedCustodian);
}
/** @notice Confirms a pending change of the custodian associated with this contract.
*
* @dev When called by the current custodian with a lock id associated with a
* pending custodian change, the `address custodian` member will be updated with the
* requested address.
*
* @param _lockId The identifier of a pending change request.
*/
function confirmCustodianChange(bytes32 _lockId) public onlyCustodian {
custodian = getCustodianChangeReq(_lockId);
delete custodianChangeReqs[_lockId];
emit CustodianChangeConfirmed(_lockId, custodian);
}
// PRIVATE FUNCTIONS
function getCustodianChangeReq(bytes32 _lockId) private view returns (address _proposedNew) {
CustodianChangeRequest storage changeRequest = custodianChangeReqs[_lockId];
// reject ‘null’ results from the map lookup
// this can only be the case if an unknown `_lockId` is received
require(changeRequest.proposedNew != 0);
return changeRequest.proposedNew;
}
/// @dev Emitted by successful `requestCustodianChange` calls.
event CustodianChangeRequested(
bytes32 _lockId,
address _msgSender,
address _proposedCustodian
);
/// @dev Emitted by successful `confirmCustodianChange` calls.
event CustodianChangeConfirmed(bytes32 _lockId, address _newCustodian);
}
/** @title A contract to inherit upgradeable token implementations.
*
* @notice A contract that provides re-usable code for upgradeable
* token implementations. It itself inherits from `CustodianUpgradable`
* as the upgrade process is controlled by the custodian.
*
* @dev This contract is intended to be inherited by any contract
* requiring a reference to the active token implementation, either
* to delegate calls to it, or authorize calls from it. This contract
* provides the mechanism for that implementation to be be replaced,
* which constitutes an implementation upgrade.
*
* @author Gemini Trust Company, LLC
*/
contract ERC20ImplUpgradeable is CustodianUpgradeable {
// TYPES
/// @dev The struct type for pending implementation changes.
struct ImplChangeRequest {
address proposedNew;
}
// MEMBERS
// @dev The reference to the active token implementation.
ERC20Impl public erc20Impl;
/// @dev The map of lock ids to pending implementation changes.
mapping (bytes32 => ImplChangeRequest) public implChangeReqs;
// CONSTRUCTOR
function ERC20ImplUpgradeable(address _custodian) CustodianUpgradeable(_custodian) public {
erc20Impl = ERC20Impl(0x0);
}
// MODIFIERS
modifier onlyImpl {
require(msg.sender == address(erc20Impl));
_;
}
// PUBLIC FUNCTIONS
// (UPGRADE)
/** @notice Requests a change of the active implementation associated
* with this contract.
*
* @dev Returns a unique lock id associated with the request.
* Anyone can call this function, but confirming the request is authorized
* by the custodian.
*
* @param _proposedImpl The address of the new active implementation.
* @return lockId A unique identifier for this request.
*/
function requestImplChange(address _proposedImpl) public returns (bytes32 lockId) {
require(_proposedImpl != address(0));
lockId = generateLockId();
implChangeReqs[lockId] = ImplChangeRequest({
proposedNew: _proposedImpl
});
emit ImplChangeRequested(lockId, msg.sender, _proposedImpl);
}
/** @notice Confirms a pending change of the active implementation
* associated with this contract.
*
* @dev When called by the custodian with a lock id associated with a
* pending change, the `ERC20Impl erc20Impl` member will be updated
* with the requested address.
*
* @param _lockId The identifier of a pending change request.
*/
function confirmImplChange(bytes32 _lockId) public onlyCustodian {
erc20Impl = getImplChangeReq(_lockId);
delete implChangeReqs[_lockId];
emit ImplChangeConfirmed(_lockId, address(erc20Impl));
}
// PRIVATE FUNCTIONS
function getImplChangeReq(bytes32 _lockId) private view returns (ERC20Impl _proposedNew) {
ImplChangeRequest storage changeRequest = implChangeReqs[_lockId];
// reject ‘null’ results from the map lookup
// this can only be the case if an unknown `_lockId` is received
require(changeRequest.proposedNew != address(0));
return ERC20Impl(changeRequest.proposedNew);
}
/// @dev Emitted by successful `requestImplChange` calls.
event ImplChangeRequested(
bytes32 _lockId,
address _msgSender,
address _proposedImpl
);
/// @dev Emitted by successful `confirmImplChange` calls.
event ImplChangeConfirmed(bytes32 _lockId, address _newImpl);
}
contract ERC20Interface {
// METHODS
// NOTE:
// public getter functions are not currently recognised as an
// implementation of the matching abstract function by the compiler.
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#name
// function name() public view returns (string);
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#symbol
// function symbol() public view returns (string);
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#totalsupply
// function decimals() public view returns (uint8);
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#totalsupply
function totalSupply() public view returns (uint256);
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#balanceof
function balanceOf(address _owner) public view returns (uint256 balance);
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#transfer
function transfer(address _to, uint256 _value) public returns (bool success);
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#transferfrom
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#approve
function approve(address _spender, uint256 _value) public returns (bool success);
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#allowance
function allowance(address _owner, address _spender) public view returns (uint256 remaining);
// EVENTS
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#transfer-1
event Transfer(address indexed _from, address indexed _to, uint256 _value);
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#approval
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
/** @title Public interface to ERC20 compliant token.
*
* @notice This contract is a permanent entry point to an ERC20 compliant
* system of contracts.
*
* @dev This contract contains no business logic and instead
* delegates to an instance of ERC20Impl. This contract also has no storage
* that constitutes the operational state of the token. This contract is
* upgradeable in the sense that the `custodian` can update the
* `erc20Impl` address, thus redirecting the delegation of business logic.
* The `custodian` is also authorized to pass custodianship.
*
* @author Gemini Trust Company, LLC
*/
contract ERC20Proxy is ERC20Interface, ERC20ImplUpgradeable {
// MEMBERS
/// @notice Returns the name of the token.
string public name;
/// @notice Returns the symbol of the token.
string public symbol;
/// @notice Returns the number of decimals the token uses.
uint8 public decimals;
// CONSTRUCTOR
function ERC20Proxy(
string _name,
string _symbol,
uint8 _decimals,
address _custodian
)
ERC20ImplUpgradeable(_custodian)
public
{
name = _name;
symbol = _symbol;
decimals = _decimals;
}
// PUBLIC FUNCTIONS
// (ERC20Interface)
/** @notice Returns the total token supply.
*
* @return the total token supply.
*/
function totalSupply() public view returns (uint256) {
return erc20Impl.totalSupply();
}
/** @notice Returns the account balance of another account with address
* `_owner`.
*
* @return balance the balance of account with address `_owner`.
*/
function balanceOf(address _owner) public view returns (uint256 balance) {
return erc20Impl.balanceOf(_owner);
}
/** @dev Internal use only.
*/
function emitTransfer(address _from, address _to, uint256 _value) public onlyImpl {
emit Transfer(_from, _to, _value);
}
/** @notice Transfers `_value` amount of tokens to address `_to`.
*
* @dev Will fire the `Transfer` event. Will revert if the `_from`
* account balance does not have enough tokens to spend.
*
* @return success true if transfer completes.
*/
function transfer(address _to, uint256 _value) public returns (bool success) {
return erc20Impl.transferWithSender(msg.sender, _to, _value);
}
/** @notice Transfers `_value` amount of tokens from address `_from`
* to address `_to`.
*
* @dev Will fire the `Transfer` event. Will revert unless the `_from`
* account has deliberately authorized the sender of the message
* via some mechanism.
*
* @return success true if transfer completes.
*/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
return erc20Impl.transferFromWithSender(msg.sender, _from, _to, _value);
}
/** @dev Internal use only.
*/
function emitApproval(address _owner, address _spender, uint256 _value) public onlyImpl {
emit Approval(_owner, _spender, _value);
}
/** @notice Allows `_spender` to withdraw from your account multiple times,
* up to the `_value` amount. If this function is called again it
* overwrites the current allowance with _value.
*
* @dev Will fire the `Approval` event.
*
* @return success true if approval completes.
*/
function approve(address _spender, uint256 _value) public returns (bool success) {
return erc20Impl.approveWithSender(msg.sender, _spender, _value);
}
/** @notice Increases the amount `_spender` is allowed to withdraw from
* your account.
* This function is implemented to avoid the race condition in standard
* ERC20 contracts surrounding the `approve` method.
*
* @dev Will fire the `Approval` event. This function should be used instead of
* `approve`.
*
* @return success true if approval completes.
*/
function increaseApproval(address _spender, uint256 _addedValue) public returns (bool success) {
return erc20Impl.increaseApprovalWithSender(msg.sender, _spender, _addedValue);
}
/** @notice Decreases the amount `_spender` is allowed to withdraw from
* your account. This function is implemented to avoid the race
* condition in standard ERC20 contracts surrounding the `approve` method.
*
* @dev Will fire the `Approval` event. This function should be used
* instead of `approve`.
*
* @return success true if approval completes.
*/
function decreaseApproval(address _spender, uint256 _subtractedValue) public returns (bool success) {
return erc20Impl.decreaseApprovalWithSender(msg.sender, _spender, _subtractedValue);
}
/** @notice Returns how much `_spender` is currently allowed to spend from
* `_owner`'s balance.
*
* @return remaining the remaining allowance.
*/
function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
return erc20Impl.allowance(_owner, _spender);
}
}
/** @title ERC20 compliant token intermediary contract holding core logic.
*
* @notice This contract serves as an intermediary between the exposed ERC20
* interface in ERC20Proxy and the store of balances in ERC20Store. This
* contract contains core logic that the proxy can delegate to
* and that the store is called by.
*
* @dev This contract contains the core logic to implement the
* ERC20 specification as well as several extensions.
* 1. Changes to the token supply.
* 2. Batched transfers.
* 3. Relative changes to spending approvals.
* 4. Delegated transfer control ('sweeping').
*
* @author Gemini Trust Company, LLC
*/
contract ERC20Impl is CustodianUpgradeable {
// TYPES
/// @dev The struct type for pending increases to the token supply (print).
struct PendingPrint {
address receiver;
uint256 value;
}
// MEMBERS
/// @dev The reference to the proxy.
ERC20Proxy public erc20Proxy;
/// @dev The reference to the store.
ERC20Store public erc20Store;
/// @dev The sole authorized caller of delegated transfer control ('sweeping').
address public sweeper;
/** @dev The static message to be signed by an external account that
* signifies their permission to forward their balance to any arbitrary
* address. This is used to consolidate the control of all accounts
* backed by a shared keychain into the control of a single key.
* Initialized as the concatenation of the address of this contract
* and the word "sweep". This concatenation is done to prevent a replay
* attack in a subsequent contract, where the sweep message could
* potentially be replayed to re-enable sweeping ability.
*/
bytes32 public sweepMsg;
/** @dev The mapping that stores whether the address in question has
* enabled sweeping its contents to another account or not.
* If an address maps to "true", it has already enabled sweeping,
* and thus does not need to re-sign the `sweepMsg` to enact the sweep.
*/
mapping (address => bool) public sweptSet;
/// @dev The map of lock ids to pending token increases.
mapping (bytes32 => PendingPrint) public pendingPrintMap;
// CONSTRUCTOR
function ERC20Impl(
address _erc20Proxy,
address _erc20Store,
address _custodian,
address _sweeper
)
CustodianUpgradeable(_custodian)
public
{
require(_sweeper != 0);
erc20Proxy = ERC20Proxy(_erc20Proxy);
erc20Store = ERC20Store(_erc20Store);
sweeper = _sweeper;
sweepMsg = keccak256(address(this), "sweep");
}
// MODIFIERS
modifier onlyProxy {
require(msg.sender == address(erc20Proxy));
_;
}
modifier onlySweeper {
require(msg.sender == sweeper);
_;
}
/** @notice Core logic of the ERC20 `approve` function.
*
* @dev This function can only be called by the referenced proxy,
* which has an `approve` function.
* Every argument passed to that function as well as the original
* `msg.sender` gets passed to this function.
* NOTE: approvals for the zero address (unspendable) are disallowed.
*
* @param _sender The address initiating the approval in proxy.
*/
function approveWithSender(
address _sender,
address _spender,
uint256 _value
)
public
onlyProxy
returns (bool success)
{
require(_spender != address(0)); // disallow unspendable approvals
erc20Store.setAllowance(_sender, _spender, _value);
erc20Proxy.emitApproval(_sender, _spender, _value);
return true;
}
/** @notice Core logic of the `increaseApproval` function.
*
* @dev This function can only be called by the referenced proxy,
* which has an `increaseApproval` function.
* Every argument passed to that function as well as the original
* `msg.sender` gets passed to this function.
* NOTE: approvals for the zero address (unspendable) are disallowed.
*
* @param _sender The address initiating the approval.
*/
function increaseApprovalWithSender(
address _sender,
address _spender,
uint256 _addedValue
)
public
onlyProxy
returns (bool success)
{
require(_spender != address(0)); // disallow unspendable approvals
uint256 currentAllowance = erc20Store.allowed(_sender, _spender);
uint256 newAllowance = currentAllowance + _addedValue;
require(newAllowance >= currentAllowance);
erc20Store.setAllowance(_sender, _spender, newAllowance);
erc20Proxy.emitApproval(_sender, _spender, newAllowance);
return true;
}
/** @notice Core logic of the `decreaseApproval` function.
*
* @dev This function can only be called by the referenced proxy,
* which has a `decreaseApproval` function.
* Every argument passed to that function as well as the original
* `msg.sender` gets passed to this function.
* NOTE: approvals for the zero address (unspendable) are disallowed.
*
* @param _sender The address initiating the approval.
*/
function decreaseApprovalWithSender(
address _sender,
address _spender,
uint256 _subtractedValue
)
public
onlyProxy
returns (bool success)
{
require(_spender != address(0)); // disallow unspendable approvals
uint256 currentAllowance = erc20Store.allowed(_sender, _spender);
uint256 newAllowance = currentAllowance - _subtractedValue;
require(newAllowance <= currentAllowance);
erc20Store.setAllowance(_sender, _spender, newAllowance);
erc20Proxy.emitApproval(_sender, _spender, newAllowance);
return true;
}
/** @notice Requests an increase in the token supply, with the newly created
* tokens to be added to the balance of the specified account.
*
* @dev Returns a unique lock id associated with the request.
* Anyone can call this function, but confirming the request is authorized
* by the custodian.
* NOTE: printing to the zero address is disallowed.
*
* @param _receiver The receiving address of the print, if confirmed.
* @param _value The number of tokens to add to the total supply and the
* balance of the receiving address, if confirmed.
*
* @return lockId A unique identifier for this request.
*/
function requestPrint(address _receiver, uint256 _value) public returns (bytes32 lockId) {
require(_receiver != address(0));
lockId = generateLockId();
pendingPrintMap[lockId] = PendingPrint({
receiver: _receiver,
value: _value
});
emit PrintingLocked(lockId, _receiver, _value);
}
/** @notice Confirms a pending increase in the token supply.
*
* @dev When called by the custodian with a lock id associated with a
* pending increase, the amount requested to be printed in the print request
* is printed to the receiving address specified in that same request.
* NOTE: this function will not execute any print that would overflow the
* total supply, but it will not revert either.
*
* @param _lockId The identifier of a pending print request.
*/
function confirmPrint(bytes32 _lockId) public onlyCustodian {
PendingPrint storage print = pendingPrintMap[_lockId];
// reject ‘null’ results from the map lookup
// this can only be the case if an unknown `_lockId` is received
address receiver = print.receiver;
require (receiver != address(0));
uint256 value = print.value;
delete pendingPrintMap[_lockId];
uint256 supply = erc20Store.totalSupply();
uint256 newSupply = supply + value;
if (newSupply >= supply) {
erc20Store.setTotalSupply(newSupply);
erc20Store.addBalance(receiver, value);
emit PrintingConfirmed(_lockId, receiver, value);
erc20Proxy.emitTransfer(address(0), receiver, value);
}
}
/** @notice Burns the specified value from the sender's balance.
*
* @dev Sender's balanced is subtracted by the amount they wish to burn.
*
* @param _value The amount to burn.
*
* @return success true if the burn succeeded.
*/
function burn(uint256 _value) public returns (bool success) {
uint256 balanceOfSender = erc20Store.balances(msg.sender);
require(_value <= balanceOfSender);
erc20Store.setBalance(msg.sender, balanceOfSender - _value);
erc20Store.setTotalSupply(erc20Store.totalSupply() - _value);
erc20Proxy.emitTransfer(msg.sender, address(0), _value);
return true;
}
/** @notice A function for a sender to issue multiple transfers to multiple
* different addresses at once. This function is implemented for gas
* considerations when someone wishes to transfer, as one transaction is
* cheaper than issuing several distinct individual `transfer` transactions.
*
* @dev By specifying a set of destination addresses and values, the
* sender can issue one transaction to transfer multiple amounts to
* distinct addresses, rather than issuing each as a separate
* transaction. The `_tos` and `_values` arrays must be equal length, and
* an index in one array corresponds to the same index in the other array
* (e.g. `_tos[0]` will receive `_values[0]`, `_tos[1]` will receive
* `_values[1]`, and so on.)
* NOTE: transfers to the zero address are disallowed.
*
* @param _tos The destination addresses to receive the transfers.
* @param _values The values for each destination address.
* @return success If transfers succeeded.
*/
function batchTransfer(address[] _tos, uint256[] _values) public returns (bool success) {
require(_tos.length == _values.length);
uint256 numTransfers = _tos.length;
uint256 senderBalance = erc20Store.balances(msg.sender);
for (uint256 i = 0; i < numTransfers; i++) {
address to = _tos[i];
require(to != address(0));
uint256 v = _values[i];
require(senderBalance >= v);
if (msg.sender != to) {
senderBalance -= v;
erc20Store.addBalance(to, v);
}
erc20Proxy.emitTransfer(msg.sender, to, v);
}
erc20Store.setBalance(msg.sender, senderBalance);
return true;
}
/** @notice Enables the delegation of transfer control for many
* accounts to the sweeper account, transferring any balances
* as well to the given destination.
*
* @dev An account delegates transfer control by signing the
* value of `sweepMsg`. The sweeper account is the only authorized
* caller of this function, so it must relay signatures on behalf
* of accounts that delegate transfer control to it. Enabling
* delegation is idempotent and permanent. If the account has a
* balance at the time of enabling delegation, its balance is
* also transfered to the given destination account `_to`.
* NOTE: transfers to the zero address are disallowed.
*
* @param _vs The array of recovery byte components of the ECDSA signatures.
* @param _rs The array of 'R' components of the ECDSA signatures.
* @param _ss The array of 'S' components of the ECDSA signatures.
* @param _to The destination for swept balances.
*/
function enableSweep(uint8[] _vs, bytes32[] _rs, bytes32[] _ss, address _to) public onlySweeper {
require(_to != address(0));
require((_vs.length == _rs.length) && (_vs.length == _ss.length));
uint256 numSignatures = _vs.length;
uint256 sweptBalance = 0;
for (uint256 i=0; i<numSignatures; ++i) {
address from = ecrecover(sweepMsg, _vs[i], _rs[i], _ss[i]);
// ecrecover returns 0 on malformed input
if (from != address(0)) {
sweptSet[from] = true;
uint256 fromBalance = erc20Store.balances(from);
if (fromBalance > 0) {
sweptBalance += fromBalance;
erc20Store.setBalance(from, 0);
erc20Proxy.emitTransfer(from, _to, fromBalance);
}
}
}
if (sweptBalance > 0) {
erc20Store.addBalance(_to, sweptBalance);
}
}
/** @notice For accounts that have delegated, transfer control
* to the sweeper, this function transfers their balances to the given
* destination.
*
* @dev The sweeper account is the only authorized caller of
* this function. This function accepts an array of addresses to have their
* balances transferred for gas efficiency purposes.
* NOTE: any address for an account that has not been previously enabled
* will be ignored.
* NOTE: transfers to the zero address are disallowed.
*
* @param _froms The addresses to have their balances swept.
* @param _to The destination address of all these transfers.
*/
function replaySweep(address[] _froms, address _to) public onlySweeper {
require(_to != address(0));
uint256 lenFroms = _froms.length;
uint256 sweptBalance = 0;
for (uint256 i=0; i<lenFroms; ++i) {
address from = _froms[i];
if (sweptSet[from]) {
uint256 fromBalance = erc20Store.balances(from);
if (fromBalance > 0) {
sweptBalance += fromBalance;
erc20Store.setBalance(from, 0);
erc20Proxy.emitTransfer(from, _to, fromBalance);
}
}
}
if (sweptBalance > 0) {
erc20Store.addBalance(_to, sweptBalance);
}
}
/** @notice Core logic of the ERC20 `transferFrom` function.
*
* @dev This function can only be called by the referenced proxy,
* which has a `transferFrom` function.
* Every argument passed to that function as well as the original
* `msg.sender` gets passed to this function.
* NOTE: transfers to the zero address are disallowed.
*
* @param _sender The address initiating the transfer in proxy.
*/
function transferFromWithSender(
address _sender,
address _from,
address _to,
uint256 _value
)
public
onlyProxy
returns (bool success)
{
require(_to != address(0)); // ensure burn is the cannonical transfer to 0x0
uint256 balanceOfFrom = erc20Store.balances(_from);
require(_value <= balanceOfFrom);
uint256 senderAllowance = erc20Store.allowed(_from, _sender);
require(_value <= senderAllowance);
erc20Store.setBalance(_from, balanceOfFrom - _value);
erc20Store.addBalance(_to, _value);
erc20Store.setAllowance(_from, _sender, senderAllowance - _value);
erc20Proxy.emitTransfer(_from, _to, _value);
return true;
}
/** @notice Core logic of the ERC20 `transfer` function.
*
* @dev This function can only be called by the referenced proxy,
* which has a `transfer` function.
* Every argument passed to that function as well as the original
* `msg.sender` gets passed to this function.
* NOTE: transfers to the zero address are disallowed.
*
* @param _sender The address initiating the transfer in proxy.
*/
function transferWithSender(
address _sender,
address _to,
uint256 _value
)
public
onlyProxy
returns (bool success)
{
require(_to != address(0)); // ensure burn is the cannonical transfer to 0x0
uint256 balanceOfSender = erc20Store.balances(_sender);
require(_value <= balanceOfSender);
erc20Store.setBalance(_sender, balanceOfSender - _value);
erc20Store.addBalance(_to, _value);
erc20Proxy.emitTransfer(_sender, _to, _value);
return true;
}
// METHODS (ERC20 sub interface impl.)
/// @notice Core logic of the ERC20 `totalSupply` function.
function totalSupply() public view returns (uint256) {
return erc20Store.totalSupply();
}
/// @notice Core logic of the ERC20 `balanceOf` function.
function balanceOf(address _owner) public view returns (uint256 balance) {
return erc20Store.balances(_owner);
}
/// @notice Core logic of the ERC20 `allowance` function.
function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
return erc20Store.allowed(_owner, _spender);
}
// EVENTS
/// @dev Emitted by successful `requestPrint` calls.
event PrintingLocked(bytes32 _lockId, address _receiver, uint256 _value);
/// @dev Emitted by successful `confirmPrint` calls.
event PrintingConfirmed(bytes32 _lockId, address _receiver, uint256 _value);
}
/** @title ERC20 compliant token balance store.
*
* @notice This contract serves as the store of balances, allowances, and
* supply for the ERC20 compliant token. No business logic exists here.
*
* @dev This contract contains no business logic and instead
* is the final destination for any change in balances, allowances, or token
* supply. This contract is upgradeable in the sense that its custodian can
* update the `erc20Impl` address, thus redirecting the source of logic that
* determines how the balances will be updated.
*
* @author Gemini Trust Company, LLC
*/
contract ERC20Store is ERC20ImplUpgradeable {
// MEMBERS
/// @dev The total token supply.
uint256 public totalSupply;
/// @dev The mapping of balances.
mapping (address => uint256) public balances;
/// @dev The mapping of allowances.
mapping (address => mapping (address => uint256)) public allowed;
// CONSTRUCTOR
function ERC20Store(address _custodian) ERC20ImplUpgradeable(_custodian) public {
totalSupply = 0;
}
// PUBLIC FUNCTIONS
// (ERC20 Ledger)
/** @notice The function to set the total supply of tokens.
*
* @dev Intended for use by token implementation functions
* that update the total supply. The only authorized caller
* is the active implementation.
*
* @param _newTotalSupply the value to set as the new total supply
*/
function setTotalSupply(
uint256 _newTotalSupply
)
public
onlyImpl
{
totalSupply = _newTotalSupply;
}
/** @notice Sets how much `_owner` allows `_spender` to transfer on behalf
* of `_owner`.
*
* @dev Intended for use by token implementation functions
* that update spending allowances. The only authorized caller
* is the active implementation.
*
* @param _owner The account that will allow an on-behalf-of spend.
* @param _spender The account that will spend on behalf of the owner.
* @param _value The limit of what can be spent.
*/
function setAllowance(
address _owner,
address _spender,
uint256 _value
)
public
onlyImpl
{
allowed[_owner][_spender] = _value;
}
/** @notice Sets the balance of `_owner` to `_newBalance`.
*
* @dev Intended for use by token implementation functions
* that update balances. The only authorized caller
* is the active implementation.
*
* @param _owner The account that will hold a new balance.
* @param _newBalance The balance to set.
*/
function setBalance(
address _owner,
uint256 _newBalance
)
public
onlyImpl
{
balances[_owner] = _newBalance;
}
/** @notice Adds `_balanceIncrease` to `_owner`'s balance.
*
* @dev Intended for use by token implementation functions
* that update balances. The only authorized caller
* is the active implementation.
* WARNING: the caller is responsible for preventing overflow.
*
* @param _owner The account that will hold a new balance.
* @param _balanceIncrease The balance to add.
*/
function addBalance(
address _owner,
uint256 _balanceIncrease
)
public
onlyImpl
{
balances[_owner] = balances[_owner] + _balanceIncrease;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_proposedCustodian","type":"address"}],"name":"requestCustodianChange","outputs":[{"name":"lockId","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"emitTransfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"custodian","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_lockId","type":"bytes32"}],"name":"confirmCustodianChange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"erc20Impl","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_proposedImpl","type":"address"}],"name":"requestImplChange","outputs":[{"name":"lockId","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"emitApproval","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_lockId","type":"bytes32"}],"name":"confirmImplChange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"implChangeReqs","outputs":[{"name":"proposedNew","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lockRequestCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"custodianChangeReqs","outputs":[{"name":"proposedNew","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"},{"name":"_custodian","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_lockId","type":"bytes32"},{"indexed":false,"name":"_msgSender","type":"address"},{"indexed":false,"name":"_proposedImpl","type":"address"}],"name":"ImplChangeRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_lockId","type":"bytes32"},{"indexed":false,"name":"_newImpl","type":"address"}],"name":"ImplChangeConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_lockId","type":"bytes32"},{"indexed":false,"name":"_msgSender","type":"address"},{"indexed":false,"name":"_proposedCustodian","type":"address"}],"name":"CustodianChangeRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_lockId","type":"bytes32"},{"indexed":false,"name":"_newCustodian","type":"address"}],"name":"CustodianChangeConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}]Contract Creation Code
6060604052341561000f57600080fd5b604051610efe380380610efe83398101604052808051820191906020018051820191906020018051919060200180516000805560018054600160a060020a038316600160a060020a0319918216179091556003805490911690559150600590508480516100809291602001906100b2565b5060068380516100949291602001906100b2565b50506007805460ff191660ff929092169190911790555061014d9050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100f357805160ff1916838001178555610120565b82800160010185558215610120579182015b82811115610120578251825591602001919060010190610105565b5061012c929150610130565b5090565b61014a91905b8082111561012c5760008155600101610136565b90565b610da28061015c6000396000f30060606040526004361061010e5763ffffffff60e060020a60003504166306fdde038114610113578063095ea7b31461019d57806315b21082146101d357806318160ddd1461020457806323b872dd1461021757806323de66511461023f578063313ce56714610269578063375b74c3146102925780633a8343ee146102c15780633c389cc4146102d757806348f9e246146102ea5780635687f2b814610309578063661884631461033157806370a08231146103535780638181b0291461037257806395d89b4114610388578063a9059cbb1461039b578063b508069b146103bd578063cb81fecf146103d3578063cf6e4488146103e6578063d73dd623146103fc578063dd62ed3e1461041e575b600080fd5b341561011e57600080fd5b610126610443565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561016257808201518382015260200161014a565b50505050905090810190601f16801561018f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156101a857600080fd5b6101bf600160a060020a03600435166024356104e1565b604051901515815260200160405180910390f35b34156101de57600080fd5b6101f2600160a060020a0360043516610564565b60405190815260200160405180910390f35b341561020f57600080fd5b6101f2610629565b341561022257600080fd5b6101bf600160a060020a0360043581169060243516604435610686565b341561024a57600080fd5b610267600160a060020a0360043581169060243516604435610711565b005b341561027457600080fd5b61027c610778565b60405160ff909116815260200160405180910390f35b341561029d57600080fd5b6102a5610781565b604051600160a060020a03909116815260200160405180910390f35b34156102cc57600080fd5b610267600435610790565b34156102e257600080fd5b6102a5610841565b34156102f557600080fd5b6101f2600160a060020a0360043516610850565b341561031457600080fd5b610267600160a060020a0360043581169060243516604435610915565b341561033c57600080fd5b6101bf600160a060020a036004351660243561097c565b341561035e57600080fd5b6101f2600160a060020a03600435166109e2565b341561037d57600080fd5b610267600435610a51565b341561039357600080fd5b610126610b02565b34156103a657600080fd5b6101bf600160a060020a0360043516602435610b6d565b34156103c857600080fd5b6102a5600435610bd3565b34156103de57600080fd5b6101f2610bee565b34156103f157600080fd5b6102a5600435610bf4565b341561040757600080fd5b6101bf600160a060020a0360043516602435610c0f565b341561042957600080fd5b6101f2600160a060020a0360043581169060243516610c75565b60058054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104d95780601f106104ae576101008083540402835291602001916104d9565b820191906000526020600020905b8154815290600101906020018083116104bc57829003601f168201915b505050505081565b600354600090600160a060020a03166389064fd233858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b5af1151561055457600080fd5b5050506040518051949350505050565b6000600160a060020a038216151561057b57600080fd5b610583610cd0565b905060206040519081016040908152600160a060020a038416825260008381526002602052208151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0391909116179055507fd76fc900a7e1a6fcf11d54b7ba943918df6c53a3128140658c389b3da1e997ba813384604051928352600160a060020a039182166020840152166040808301919091526060909101905180910390a1919050565b600354600090600160a060020a03166318160ddd6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561066b57600080fd5b5af1151561067857600080fd5b505050604051805191505090565b600354600090600160a060020a0316635d5e22cd3386868660405160e060020a63ffffffff8716028152600160a060020a0394851660048201529284166024840152921660448201526064810191909152608401602060405180830381600087803b15156106f357600080fd5b5af1151561070057600080fd5b505050604051805195945050505050565b60035433600160a060020a0390811691161461072c57600080fd5b81600160a060020a031683600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405190815260200160405180910390a3505050565b60075460ff1681565b600154600160a060020a031681565b60015433600160a060020a039081169116146107ab57600080fd5b6107b481610d1e565b60018054600160a060020a0392831673ffffffffffffffffffffffffffffffffffffffff1991821617825560008481526002602052604090819020805490921690915590547f9a99272c0f6b7a30ef9e76e684a7cd408bfd4f11a72f36a8e276253c920e442d92849291169051918252600160a060020a031660208201526040908101905180910390a150565b600354600160a060020a031681565b6000600160a060020a038216151561086757600080fd5b61086f610cd0565b905060206040519081016040908152600160a060020a038416825260008381526004602052208151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0391909116179055507f5df12834436b8dc248df3f7f1796a3e39f851d610be49cdcd92514fa821b9f97813384604051928352600160a060020a039182166020840152166040808301919091526060909101905180910390a1919050565b60035433600160a060020a0390811691161461093057600080fd5b81600160a060020a031683600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405190815260200160405180910390a3505050565b600354600090600160a060020a03166361e1077d33858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600354600090600160a060020a03166370a082318360405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b1515610a3557600080fd5b5af11515610a4257600080fd5b50505060405180519392505050565b60015433600160a060020a03908116911614610a6c57600080fd5b610a7581610d52565b60038054600160a060020a0392831673ffffffffffffffffffffffffffffffffffffffff1991821617825560008481526004602052604090819020805490921690915590547f9d55b0349a0a4c5b511f72228170bb91d45c9ac78dba8ab5b4175d3ed42f06b392849291169051918252600160a060020a031660208201526040908101905180910390a150565b60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104d95780601f106104ae576101008083540402835291602001916104d9565b600354600090600160a060020a031663dfe0f0ca33858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600460205260009081526040902054600160a060020a031681565b60005481565b600260205260009081526040902054600160a060020a031681565b600354600090600160a060020a0316632e0179b533858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600354600090600160a060020a031663dd62ed3e848460405160e060020a63ffffffff8516028152600160a060020a03928316600482015291166024820152604401602060405180830381600087803b151561054757600080fd5b60008054600101808255600019430140903090604051928352600160a060020a03919091166c0100000000000000000000000002602083015260348201526054016040518091039020905090565b60008181526002602052604081208054600160a060020a03161515610d4257600080fd5b54600160a060020a031692915050565b60008181526004602052604081208054600160a060020a03161515610d4257600080fd00a165627a7a72305820e9510794af44fba3b1d3c8d2d27f071e428847cc4b56c82a806ad15368cfc00b0029000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000dffc66191baf5047866033d2fe400907af4038a8000000000000000000000000000000000000000000000000000000000000000d47656d696e6920646f6c6c61720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044755534400000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x60606040526004361061010e5763ffffffff60e060020a60003504166306fdde038114610113578063095ea7b31461019d57806315b21082146101d357806318160ddd1461020457806323b872dd1461021757806323de66511461023f578063313ce56714610269578063375b74c3146102925780633a8343ee146102c15780633c389cc4146102d757806348f9e246146102ea5780635687f2b814610309578063661884631461033157806370a08231146103535780638181b0291461037257806395d89b4114610388578063a9059cbb1461039b578063b508069b146103bd578063cb81fecf146103d3578063cf6e4488146103e6578063d73dd623146103fc578063dd62ed3e1461041e575b600080fd5b341561011e57600080fd5b610126610443565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561016257808201518382015260200161014a565b50505050905090810190601f16801561018f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156101a857600080fd5b6101bf600160a060020a03600435166024356104e1565b604051901515815260200160405180910390f35b34156101de57600080fd5b6101f2600160a060020a0360043516610564565b60405190815260200160405180910390f35b341561020f57600080fd5b6101f2610629565b341561022257600080fd5b6101bf600160a060020a0360043581169060243516604435610686565b341561024a57600080fd5b610267600160a060020a0360043581169060243516604435610711565b005b341561027457600080fd5b61027c610778565b60405160ff909116815260200160405180910390f35b341561029d57600080fd5b6102a5610781565b604051600160a060020a03909116815260200160405180910390f35b34156102cc57600080fd5b610267600435610790565b34156102e257600080fd5b6102a5610841565b34156102f557600080fd5b6101f2600160a060020a0360043516610850565b341561031457600080fd5b610267600160a060020a0360043581169060243516604435610915565b341561033c57600080fd5b6101bf600160a060020a036004351660243561097c565b341561035e57600080fd5b6101f2600160a060020a03600435166109e2565b341561037d57600080fd5b610267600435610a51565b341561039357600080fd5b610126610b02565b34156103a657600080fd5b6101bf600160a060020a0360043516602435610b6d565b34156103c857600080fd5b6102a5600435610bd3565b34156103de57600080fd5b6101f2610bee565b34156103f157600080fd5b6102a5600435610bf4565b341561040757600080fd5b6101bf600160a060020a0360043516602435610c0f565b341561042957600080fd5b6101f2600160a060020a0360043581169060243516610c75565b60058054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104d95780601f106104ae576101008083540402835291602001916104d9565b820191906000526020600020905b8154815290600101906020018083116104bc57829003601f168201915b505050505081565b600354600090600160a060020a03166389064fd233858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b5af1151561055457600080fd5b5050506040518051949350505050565b6000600160a060020a038216151561057b57600080fd5b610583610cd0565b905060206040519081016040908152600160a060020a038416825260008381526002602052208151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0391909116179055507fd76fc900a7e1a6fcf11d54b7ba943918df6c53a3128140658c389b3da1e997ba813384604051928352600160a060020a039182166020840152166040808301919091526060909101905180910390a1919050565b600354600090600160a060020a03166318160ddd6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561066b57600080fd5b5af1151561067857600080fd5b505050604051805191505090565b600354600090600160a060020a0316635d5e22cd3386868660405160e060020a63ffffffff8716028152600160a060020a0394851660048201529284166024840152921660448201526064810191909152608401602060405180830381600087803b15156106f357600080fd5b5af1151561070057600080fd5b505050604051805195945050505050565b60035433600160a060020a0390811691161461072c57600080fd5b81600160a060020a031683600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405190815260200160405180910390a3505050565b60075460ff1681565b600154600160a060020a031681565b60015433600160a060020a039081169116146107ab57600080fd5b6107b481610d1e565b60018054600160a060020a0392831673ffffffffffffffffffffffffffffffffffffffff1991821617825560008481526002602052604090819020805490921690915590547f9a99272c0f6b7a30ef9e76e684a7cd408bfd4f11a72f36a8e276253c920e442d92849291169051918252600160a060020a031660208201526040908101905180910390a150565b600354600160a060020a031681565b6000600160a060020a038216151561086757600080fd5b61086f610cd0565b905060206040519081016040908152600160a060020a038416825260008381526004602052208151815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0391909116179055507f5df12834436b8dc248df3f7f1796a3e39f851d610be49cdcd92514fa821b9f97813384604051928352600160a060020a039182166020840152166040808301919091526060909101905180910390a1919050565b60035433600160a060020a0390811691161461093057600080fd5b81600160a060020a031683600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405190815260200160405180910390a3505050565b600354600090600160a060020a03166361e1077d33858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600354600090600160a060020a03166370a082318360405160e060020a63ffffffff8416028152600160a060020a039091166004820152602401602060405180830381600087803b1515610a3557600080fd5b5af11515610a4257600080fd5b50505060405180519392505050565b60015433600160a060020a03908116911614610a6c57600080fd5b610a7581610d52565b60038054600160a060020a0392831673ffffffffffffffffffffffffffffffffffffffff1991821617825560008481526004602052604090819020805490921690915590547f9d55b0349a0a4c5b511f72228170bb91d45c9ac78dba8ab5b4175d3ed42f06b392849291169051918252600160a060020a031660208201526040908101905180910390a150565b60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104d95780601f106104ae576101008083540402835291602001916104d9565b600354600090600160a060020a031663dfe0f0ca33858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600460205260009081526040902054600160a060020a031681565b60005481565b600260205260009081526040902054600160a060020a031681565b600354600090600160a060020a0316632e0179b533858560405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561054757600080fd5b600354600090600160a060020a031663dd62ed3e848460405160e060020a63ffffffff8516028152600160a060020a03928316600482015291166024820152604401602060405180830381600087803b151561054757600080fd5b60008054600101808255600019430140903090604051928352600160a060020a03919091166c0100000000000000000000000002602083015260348201526054016040518091039020905090565b60008181526002602052604081208054600160a060020a03161515610d4257600080fd5b54600160a060020a031692915050565b60008181526004602052604081208054600160a060020a03161515610d4257600080fd00a165627a7a72305820e9510794af44fba3b1d3c8d2d27f071e428847cc4b56c82a806ad15368cfc00b0029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000dffc66191baf5047866033d2fe400907af4038a8000000000000000000000000000000000000000000000000000000000000000d47656d696e6920646f6c6c61720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044755534400000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Gemini dollar
Arg [1] : _symbol (string): GUSD
Arg [2] : _decimals (uint8): 2
Arg [3] : _custodian (address): 0xdFfC66191bAf5047866033d2Fe400907Af4038a8
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [3] : 000000000000000000000000dffc66191baf5047866033d2fe400907af4038a8
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [5] : 47656d696e6920646f6c6c617200000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 4755534400000000000000000000000000000000000000000000000000000000
Swarm Source
bzzr://e9510794af44fba3b1d3c8d2d27f071e428847cc4b56c82a806ad15368cfc00b
Loading...
Loading
Loading...
Loading
OVERVIEW
Gemini dollar combines the creditworthiness and price stability of the U.S. dollar with blockchain technology and the oversight of U.S. regulators.Net Worth in USD
$90,736.26
Net Worth in ETH
45.931625
Token Allocations
GUSD
98.68%
TERK
0.51%
USDT
0.50%
Others
0.31%
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 98.68% | $0.99916 | 89,614.98 | $89,539.7 | |
| ETH | 0.50% | $0.999676 | 450.864 | $450.72 | |
| ETH | 0.02% | $0.295343 | 62.5045 | $18.46 | |
| ETH | <0.01% | $0.109028 | 1 | $0.109 | |
| ETH | <0.01% | $0.022046 | 4.5683 | $0.1007 | |
| BSC | 0.51% | $0.046323 | 10,000 | $463.23 | |
| BSC | 0.28% | $0.025633 | 10,000 | $256.33 | |
| BSC | <0.01% | $0.000089 | 50,000 | $4.43 | |
| BASE | <0.01% | $0.019895 | 160 | $3.18 |
Loading...
Loading
Loading...
Loading
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.