Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract contains unverified libraries: SmartWalletLib
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
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
- No Contract Security Audit Submitted- Submit Audit Here
[{"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
Swarm Source
bzzr://5073597116b7b71c0560d912d3593a9c23c16b370d182ba2ea2d28defe0ce4b3
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.