ETH Price: $2,621.72 (-1.84%)
Gas: 1 Gwei

Contract

0x00859faAc0C70B1A34F1de4C7b062273C9f79e78
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set User Withdra...65191482018-10-15 10:24:362125 days ago1539599076IN
0x00859faA...3C9f79e78
0 ETH0.0004697410
0x6080604064456962018-10-03 12:29:492137 days ago1538569789IN
 Contract Creation
0 ETH0.001796945

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x88f49Da7...e0cD135FF
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
SmartWallet

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-10-08
*/

pragma solidity ^0.4.24;

contract IERC20Token {
    // these functions aren't abstract since the compiler emits automatically generated getter functions as external
    function name() public constant returns (string) {}
    function symbol() public constant returns (string) {}
    function decimals() public constant returns (uint8) {}
    function totalSupply() public constant returns (uint256) {}
    function balanceOf(address _owner) public constant returns (uint256) { _owner; }
    function allowance(address _owner, address _spender) public constant returns (uint256) { _owner; _spender; }

    function transfer(address _to, uint256 _value) public returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
    function approve(address _spender, uint256 _value) public returns (bool success);
}

contract Ownable {
    address public owner;
    address public newOwner;

    event OwnerUpdate(address _prevOwner, address _newOwner);

    /*
        @dev constructor
    */
    constructor (address _owner) public {
        owner = _owner;
    }

    /*
        @dev allows execution by the owner only
    */
    modifier ownerOnly {
        require(msg.sender == owner);
        _;
    }

    /*
        @dev allows transferring the contract ownership
        the new owner still needs to accept the transfer
        can only be called by the contract owner

        @param _newOwner    new contract owner
    */
    function transferOwnership(address _newOwner) public ownerOnly {
        require(_newOwner != owner);
        newOwner = _newOwner;
    }

    /*
        @dev used by a new owner to accept an ownership transfer
    */
    function acceptOwnership() public {
        require(msg.sender == newOwner);
        emit OwnerUpdate(owner, newOwner);
        owner = newOwner;
        newOwner = address(0);
    }
}

contract Utils {
    /*
        @dev constructor
    */
    constructor() public {
    }

    /*
        @dev verifies that an amount is greater than zero
    */
    modifier greaterThanZero(uint256 _amount) {
        require(_amount > 0);
        _;
    }

    /*
        @dev validates an address - currently only checks that it isn't null
    */
    modifier validAddress(address _address) {
        require(_address != 0x0);
        _;
    }

    /*
        @dev verifies that the address is different than this contract address
    */
    modifier notThis(address _address) {
        require(_address != address(this));
        _;
    }

    /*
        @dev verifies that the string is not empty
    */
    modifier notEmpty(string _str) {
        require(bytes(_str).length > 0);
        _;
    }

    // Overflow protected math functions

    /*
        @dev returns the sum of _x and _y, asserts if the calculation overflows

        @param _x   value 1
        @param _y   value 2

        @return sum
    */
    function safeAdd(uint256 _x, uint256 _y) internal pure returns (uint256) {
        uint256 z = _x + _y;
        assert(z >= _x);
        return z;
    }

    /*
        @dev returns the difference of _x minus _y, asserts if the subtraction results in a negative number

        @param _x   minuend
        @param _y   subtrahend

        @return difference
    */
    function safeSub(uint256 _x, uint256 _y) internal pure returns (uint256) {
        require(_x >= _y);
        return _x - _y;
    }

    /*
        @dev returns the product of multiplying _x by _y, asserts if the calculation overflows

        @param _x   factor 1
        @param _y   factor 2

        @return product
    */
    function safeMul(uint256 _x, uint256 _y) internal pure returns (uint256) {
        uint256 z = _x * _y;
        assert(_x == 0 || z / _x == _y);
        return z;
    }
}

contract WithdrawalConfigurations is Ownable, Utils {
    
    /*
     *  Members
     */

    uint public      minWithdrawalCoolingPeriod;
    uint constant    maxWithdrawalCoolingPeriod = 12 * 1 weeks; // = 14515200 seconds
    uint public      withdrawalCoolingPeriod;
   
    /*
     *  Events
     */
    event WithdrawalRequested(address _sender, address _smartWallet);
    event SetWithdrawalCoolingPeriod(uint _withdrawalCoolingPeriod);

    /*
        @dev constructor

        @param _withdrawalCoolingPeriod       The cooling period 
        @param _minWithdrawalCoolingPeriod    The minimum time from withdraw request to allow performing it

    */
    constructor (uint _withdrawalCoolingPeriod, uint _minWithdrawalCoolingPeriod) 
        Ownable(msg.sender)
        public
        {
            require(_withdrawalCoolingPeriod <= maxWithdrawalCoolingPeriod &&
                    _withdrawalCoolingPeriod >= _minWithdrawalCoolingPeriod);
            require(_minWithdrawalCoolingPeriod >= 0);

            minWithdrawalCoolingPeriod = _minWithdrawalCoolingPeriod;
            withdrawalCoolingPeriod = _withdrawalCoolingPeriod;
       }

    /*
        @dev Get the withdrawalCoolingPeriod parameter value. 
   
     */
    function getWithdrawalCoolingPeriod() external view returns(uint) {
        return withdrawalCoolingPeriod;
    }

    /*
        @dev Set the withdrawalCoolingPeriod parameter value. 

        @param _withdrawalCoolingPeriod   Cooling period in seconds
     */
    function setWithdrawalCoolingPeriod(uint _withdrawalCoolingPeriod)
        ownerOnly()
        public
        {
            require (_withdrawalCoolingPeriod <= maxWithdrawalCoolingPeriod &&
                     _withdrawalCoolingPeriod >= minWithdrawalCoolingPeriod);
            withdrawalCoolingPeriod = _withdrawalCoolingPeriod;
            emit SetWithdrawalCoolingPeriod(_withdrawalCoolingPeriod);
    }

    /*
        @dev Fire the WithdrawalRequested event. 

        @param _sender          The user account, activating this request
        @param _smartWallet     The smart wallet that the request was called upon   
     */
    function emitWithrawalRequestEvent(address _sender, address _smartWallet) 
        public
        {
            emit WithdrawalRequested(_sender, _smartWallet);
    }
}

library SmartWalletLib {

    /*
     *  Structs
     */ 
    struct Wallet {
        address operatorAccount;
        address userWithdrawalAccount;
        address feesAccount;
        uint    withdrawAllowedAt; // In seconds
    }

    /*
     *  Members
     */
    string constant VERSION = "1.1";
    address constant withdrawalConfigurationsContract = 0xDdD336eAad17F1D40cc81997Fb956608f00639FF; 
    
    /*
     *  Modifiers
     */
    modifier validAddress(address _address) {
        require(_address != 0x0);
        _;
    }

    modifier addressNotSet(address _address) {
        require(_address == 0);
        _;
    }

    modifier operatorOnly(address _operatorAccount) {
        require(msg.sender == _operatorAccount);
        _;
    }

    modifier userWithdrawalAccountOnly(Wallet storage _self) {
        require(msg.sender == _self.userWithdrawalAccount);
        _;
    }

    /*
     *  Events
     */
    event TransferToUserWithdrawalAccount(address _token, address _userWithdrawalAccount, uint _amount, address _feesToken, address _feesAccount, uint _fee);
    event SetUserWithdrawalAccount(address _userWithdrawalAccount);
    event PerformUserWithdraw(address _token, address _userWithdrawalAccount, uint _amount);
    
    /*
        @dev Initialize the wallet with the operator and backupAccount address
        
        @param _self                        Wallet storage
        @param _operator                    The operator account
        @param _feesAccount                 The account to transfer fees to
    */
    function initWallet(Wallet storage _self, address _operator, address _feesAccount) 
            public
            validAddress(_operator)
            validAddress(_feesAccount)
            {
        
                _self.operatorAccount = _operator;
                _self.feesAccount = _feesAccount;
    }

    /*
        @dev Setting the account of the user to send funds to. 
        
        @param _self                        Wallet storage
        @param _userWithdrawalAccount       The user account to withdraw funds to
    */
    function setUserWithdrawalAccount(Wallet storage _self, address _userWithdrawalAccount) 
            public
            operatorOnly(_self.operatorAccount)
            validAddress(_userWithdrawalAccount)
            addressNotSet(_self.userWithdrawalAccount)
            {
        
                _self.userWithdrawalAccount = _userWithdrawalAccount;
                emit SetUserWithdrawalAccount(_userWithdrawalAccount);
    }
    
    /*
        @dev Withdraw funds to the user account. 

        @param _self                Wallet storage
        @param _token               The ERC20 token the owner withdraws from 
        @param _amount              Amount to transfer  
        @param _fee                 Fee to transfer   
    */
    function transferToUserWithdrawalAccount(Wallet storage _self, IERC20Token _token, uint _amount, IERC20Token _feesToken, uint _fee) 
            public 
            operatorOnly(_self.operatorAccount)
            validAddress(_self.userWithdrawalAccount)
            {

                if (_fee > 0) {        
                    _feesToken.transfer(_self.feesAccount, _fee); 
                }       
                
                _token.transfer(_self.userWithdrawalAccount, _amount);
                emit TransferToUserWithdrawalAccount(_token, _self.userWithdrawalAccount, _amount,  _feesToken, _self.feesAccount, _fee);   
        
    }

    /*
        @dev returns the sum of _x and _y, asserts if the calculation overflows

        @param _x   value 1
        @param _y   value 2

        @return sum
    */
    function safeAdd(uint256 _x, uint256 _y) internal pure returns (uint256) {
        uint256 z = _x + _y;
        assert(z >= _x);
        return z;
    }
    
    /*
        @dev user request withdraw. 

        @param _self                Wallet storage
        @param _token               The ERC20 token the owner withdraws from 
        
    */
    function requestWithdraw(Wallet storage _self) 
        public 
        userWithdrawalAccountOnly(_self)
        {
            
            WithdrawalConfigurations withdrawalConfigurations = WithdrawalConfigurations(withdrawalConfigurationsContract);
            
            _self.withdrawAllowedAt = safeAdd(now, withdrawalConfigurations.getWithdrawalCoolingPeriod());

            withdrawalConfigurations.emitWithrawalRequestEvent(msg.sender, address(this));
    }

    /*
        @dev user perform withdraw. 

        @param _self                Wallet storage
        @param _token               The ERC20 token the owner withdraws from 
        
    */
    function performUserWithdraw(Wallet storage _self, IERC20Token _token)
        public
        userWithdrawalAccountOnly(_self)
        {
            require(_self.withdrawAllowedAt != 0 &&
                    _self.withdrawAllowedAt <= now );

            uint userBalance = _token.balanceOf(this);
            _token.transfer(_self.userWithdrawalAccount, userBalance);
            emit PerformUserWithdraw(_token, _self.userWithdrawalAccount, userBalance);   
        }

}

contract SmartWallet {

    /*
     *  Members
     */
    using SmartWalletLib for SmartWalletLib.Wallet;
    SmartWalletLib.Wallet public wallet;
       
   // Wallet public wallet;
    /*
     *  Events
     */
    event TransferToUserWithdrawalAccount(address _token, address _userWithdrawalAccount, uint _amount, address _feesToken, address _feesAccount, uint _fee);
    event SetUserWithdrawalAccount(address _userWithdrawalAccount);
    event PerformUserWithdraw(address _token, address _userWithdrawalAccount, uint _amount);
     
    /*
        @dev constructor

        @param _backupAccount       A default operator's account to send funds to, in cases where the user account is
                                    unavailable or lost
        @param _operator            The contract operator address
        @param _feesAccount         The account to transfer fees to 

    */
    constructor (address _operator, address _feesAccount) public {
        wallet.initWallet(_operator, _feesAccount);
    }

    /*
        @dev Setting the account of the user to send funds to. 
        
        @param _userWithdrawalAccount       The user account to withdraw funds to
        
    */
    function setUserWithdrawalAccount(address _userWithdrawalAccount) public {
        wallet.setUserWithdrawalAccount(_userWithdrawalAccount);
    }

    /*
        @dev Withdraw funds to the user account. 


        @param _token               The ERC20 token the owner withdraws from 
        @param _amount              Amount to transfer    
    */
    function transferToUserWithdrawalAccount(IERC20Token _token, uint _amount, IERC20Token _feesToken, uint _fee) public {
        wallet.transferToUserWithdrawalAccount(_token, _amount, _feesToken, _fee);
    }

    /*
        @dev Allows the user to request a withdraw of his/her placements
        
        @param _token               The ERC20 token the user wishes to withdraw from 
    */
    function requestWithdraw() public {
        wallet.requestWithdraw();
    }

    /*
        @dev Allows the user to perform the requestWithdraw operation
        
        @param _token               The ERC20 token the user withdraws from 
    */
    function performUserWithdraw(IERC20Token _token) public {
        wallet.performUserWithdraw(_token);
    }
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_feesToken","type":"address"},{"name":"_fee","type":"uint256"}],"name":"transferToUserWithdrawalAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"wallet","outputs":[{"name":"operatorAccount","type":"address"},{"name":"userWithdrawalAccount","type":"address"},{"name":"feesAccount","type":"address"},{"name":"withdrawAllowedAt","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"performUserWithdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"requestWithdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_userWithdrawalAccount","type":"address"}],"name":"setUserWithdrawalAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_operator","type":"address"},{"name":"_feesAccount","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_token","type":"address"},{"indexed":false,"name":"_userWithdrawalAccount","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_feesToken","type":"address"},{"indexed":false,"name":"_feesAccount","type":"address"},{"indexed":false,"name":"_fee","type":"uint256"}],"name":"TransferToUserWithdrawalAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_userWithdrawalAccount","type":"address"}],"name":"SetUserWithdrawalAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_token","type":"address"},{"indexed":false,"name":"_userWithdrawalAccount","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"PerformUserWithdraw","type":"event"}]

Deployed Bytecode

0x60806040526004361061006c5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631d9082c48114610071578063521eb273146100a15780639219baa4146100eb578063b3423eec1461010c578063fe35530c14610121575b600080fd5b34801561007d57600080fd5b5061009f600160a060020a036004358116906024359060443516606435610142565b005b3480156100ad57600080fd5b506100b66101ee565b60408051600160a060020a03958616815293851660208501529190931682820152606082019290925290519081900360800190f35b3480156100f757600080fd5b5061009f600160a060020a0360043516610211565b34801561011857600080fd5b5061009f6102a4565b34801561012d57600080fd5b5061009f600160a060020a0360043516610327565b604080517f1557a52f000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a03808816602484015260448301879052851660648301526084820184905291517374ba8c8f53809bd3baa0c243350cb989f6c9dc3c92631557a52f9260a48082019391829003018186803b1580156101d057600080fd5b505af41580156101e4573d6000803e3d6000fd5b5050505050505050565b600054600154600254600354600160a060020a0393841693928316929091169084565b604080517fb2d07945000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517374ba8c8f53809bd3baa0c243350cb989f6c9dc3c9263b2d079459260448082019391829003018186803b15801561028957600080fd5b505af415801561029d573d6000803e3d6000fd5b5050505050565b604080517f3be5e49f00000000000000000000000000000000000000000000000000000000815260006004820181905291517374ba8c8f53809bd3baa0c243350cb989f6c9dc3c92633be5e49f9260248082019391829003018186803b15801561030d57600080fd5b505af4158015610321573d6000803e3d6000fd5b50505050565b604080517f2eb9e5d7000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517374ba8c8f53809bd3baa0c243350cb989f6c9dc3c92632eb9e5d79260448082019391829003018186803b15801561028957600080fd00a165627a7a723058205073597116b7b71c0560d912d3593a9c23c16b370d182ba2ea2d28defe0ce4b30029

Libraries Used


Swarm Source

bzzr://5073597116b7b71c0560d912d3593a9c23c16b370d182ba2ea2d28defe0ce4b3

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ 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.