More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
11984262 | 1384 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Minimal Proxy Contract for 0xe5857440bbff64c98ceb70d650805e1e96adde7a
Contract Name:
WalletImpl
Compiler Version
v0.7.0+commit.9e61f92b
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-11-08 */ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.7.0; // File: contracts/lib/Ownable.sol // Copyright 2017 Loopring Technology Limited. /// @title Ownable /// @author Brecht Devos - <[email protected]> /// @dev The Ownable contract has an owner address, and provides basic /// authorization control functions, this simplifies the implementation of /// "user permissions". contract Ownable { address public owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /// @dev The Ownable constructor sets the original `owner` of the contract /// to the sender. constructor() { owner = msg.sender; } /// @dev Throws if called by any account other than the owner. modifier onlyOwner() { require(msg.sender == owner, "UNAUTHORIZED"); _; } /// @dev Allows the current owner to transfer control of the contract to a /// new owner. /// @param newOwner The address to transfer ownership to. function transferOwnership( address newOwner ) public virtual onlyOwner { require(newOwner != address(0), "ZERO_ADDRESS"); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } function renounceOwnership() public onlyOwner { emit OwnershipTransferred(owner, address(0)); owner = address(0); } } // File: contracts/iface/Wallet.sol // Copyright 2017 Loopring Technology Limited. /// @title Wallet /// @dev Base contract for smart wallets. /// Sub-contracts must NOT use non-default constructor to initialize /// wallet states, instead, `init` shall be used. This is to enable /// proxies to be deployed in front of the real wallet contract for /// saving gas. /// /// @author Daniel Wang - <[email protected]> interface Wallet { function version() external pure returns (string memory); function owner() external view returns (address); /// @dev Set a new owner. function setOwner(address newOwner) external; /// @dev Adds a new module. The `init` method of the module /// will be called with `address(this)` as the parameter. /// This method must throw if the module has already been added. /// @param _module The module's address. function addModule(address _module) external; /// @dev Removes an existing module. This method must throw if the module /// has NOT been added or the module is the wallet's only module. /// @param _module The module's address. function removeModule(address _module) external; /// @dev Checks if a module has been added to this wallet. /// @param _module The module to check. /// @return True if the module exists; False otherwise. function hasModule(address _module) external view returns (bool); /// @dev Binds a method from the given module to this /// wallet so the method can be invoked using this wallet's default /// function. /// Note that this method must throw when the given module has /// not been added to this wallet. /// @param _method The method's 4-byte selector. /// @param _module The module's address. Use address(0) to unbind the method. function bindMethod(bytes4 _method, address _module) external; /// @dev Returns the module the given method has been bound to. /// @param _method The method's 4-byte selector. /// @return _module The address of the bound module. If no binding exists, /// returns address(0) instead. function boundMethodModule(bytes4 _method) external view returns (address _module); /// @dev Performs generic transactions. Any module that has been added to this /// wallet can use this method to transact on any third-party contract with /// msg.sender as this wallet itself. /// /// Note: 1) this method must ONLY allow invocations from a module that has /// been added to this wallet. The wallet owner shall NOT be permitted /// to call this method directly. 2) Reentrancy inside this function should /// NOT cause any problems. /// /// @param mode The transaction mode, 1 for CALL, 2 for DELEGATECALL. /// @param to The desitination address. /// @param value The amount of Ether to transfer. /// @param data The data to send over using `to.call{value: value}(data)` /// @return returnData The transaction's return value. function transact( uint8 mode, address to, uint value, bytes calldata data ) external returns (bytes memory returnData); } // File: contracts/iface/Module.sol // Copyright 2017 Loopring Technology Limited. /// @title Module /// @dev Base contract for all smart wallet modules. /// /// @author Daniel Wang - <[email protected]> interface Module { /// @dev Activates the module for the given wallet (msg.sender) after the module is added. /// Warning: this method shall ONLY be callable by a wallet. function activate() external; /// @dev Deactivates the module for the given wallet (msg.sender) before the module is removed. /// Warning: this method shall ONLY be callable by a wallet. function deactivate() external; } // File: contracts/lib/ERC20.sol // Copyright 2017 Loopring Technology Limited. /// @title ERC20 Token Interface /// @dev see https://github.com/ethereum/EIPs/issues/20 /// @author Daniel Wang - <[email protected]> abstract contract ERC20 { function totalSupply() public view virtual returns (uint); function balanceOf( address who ) public view virtual returns (uint); function allowance( address owner, address spender ) public view virtual returns (uint); function transfer( address to, uint value ) public virtual returns (bool); function transferFrom( address from, address to, uint value ) public virtual returns (bool); function approve( address spender, uint value ) public virtual returns (bool); } // File: contracts/lib/ReentrancyGuard.sol // Copyright 2017 Loopring Technology Limited. /// @title ReentrancyGuard /// @author Brecht Devos - <[email protected]> /// @dev Exposes a modifier that guards a function against reentrancy /// Changing the value of the same storage value multiple times in a transaction /// is cheap (starting from Istanbul) so there is no need to minimize /// the number of times the value is changed contract ReentrancyGuard { //The default value must be 0 in order to work behind a proxy. uint private _guardValue; modifier nonReentrant() { require(_guardValue == 0, "REENTRANCY"); _guardValue = 1; _; _guardValue = 0; } } // File: contracts/iface/ModuleRegistry.sol // Copyright 2017 Loopring Technology Limited. /// @title ModuleRegistry /// @dev A registry for modules. /// /// @author Daniel Wang - <[email protected]> interface ModuleRegistry { /// @dev Registers and enables a new module. function registerModule(address module) external; /// @dev Disables a module function disableModule(address module) external; /// @dev Returns true if the module is registered and enabled. function isModuleEnabled(address module) external view returns (bool); /// @dev Returns the list of enabled modules. function enabledModules() external view returns (address[] memory _modules); /// @dev Returns the number of enbaled modules. function numOfEnabledModules() external view returns (uint); /// @dev Returns true if the module is ever registered. function isModuleRegistered(address module) external view returns (bool); } // File: contracts/base/Controller.sol // Copyright 2017 Loopring Technology Limited. /// @title Controller /// /// @author Daniel Wang - <[email protected]> abstract contract Controller { function moduleRegistry() external view virtual returns (ModuleRegistry); function walletFactory() external view virtual returns (address); } // File: contracts/base/BaseWallet.sol // Copyright 2017 Loopring Technology Limited. /// @title BaseWallet /// @dev This contract provides basic implementation for a Wallet. /// /// @author Daniel Wang - <[email protected]> abstract contract BaseWallet is ReentrancyGuard, Wallet { // WARNING: do not delete wallet state data to make this implementation // compatible with early versions. // // ----- DATA LAYOUT BEGINS ----- address internal _owner; mapping (address => bool) private modules; Controller public controller; mapping (bytes4 => address) internal methodToModule; // ----- DATA LAYOUT ENDS ----- event OwnerChanged (address newOwner); event ControllerChanged (address newController); event ModuleAdded (address module); event ModuleRemoved (address module); event MethodBound (bytes4 method, address module); event WalletSetup (address owner); modifier onlyFromModule { require(modules[msg.sender], "MODULE_UNAUTHORIZED"); _; } modifier onlyFromFactory { require( msg.sender == controller.walletFactory(), "UNAUTHORIZED" ); _; } /// @dev We need to make sure the Factory address cannot be changed without wallet owner's /// explicit authorization. modifier onlyFromFactoryOrModule { require( modules[msg.sender] || msg.sender == controller.walletFactory(), "UNAUTHORIZED" ); _; } /// @dev Set up this wallet by assigning an original owner /// /// Note that calling this method more than once will throw. /// /// @param _initialOwner The owner of this wallet, must not be address(0). function initOwner( address _initialOwner ) external onlyFromFactory { require(controller != Controller(0), "NO_CONTROLLER"); require(_owner == address(0), "INITIALIZED_ALREADY"); require(_initialOwner != address(0), "ZERO_ADDRESS"); _owner = _initialOwner; emit WalletSetup(_initialOwner); } /// @dev Set up this wallet by assigning a controller and initial modules. /// /// Note that calling this method more than once will throw. /// And this method must be invoked before owner is initialized /// /// @param _controller The Controller instance. /// @param _modules The initial modules. function init( Controller _controller, address[] calldata _modules ) external { require( _owner == address(0) && controller == Controller(0) && _controller != Controller(0), "CONTROLLER_INIT_FAILED" ); controller = _controller; ModuleRegistry moduleRegistry = controller.moduleRegistry(); for (uint i = 0; i < _modules.length; i++) { _addModule(_modules[i], moduleRegistry); } } function owner() override public view returns (address) { return _owner; } function setOwner(address newOwner) external override onlyFromModule { require(newOwner != address(0), "ZERO_ADDRESS"); require(newOwner != address(this), "PROHIBITED"); require(newOwner != _owner, "SAME_ADDRESS"); _owner = newOwner; emit OwnerChanged(newOwner); } function setController(Controller newController) external onlyFromModule { require(newController != controller, "SAME_CONTROLLER"); require(newController != Controller(0), "INVALID_CONTROLLER"); controller = newController; emit ControllerChanged(address(newController)); } function addModule(address _module) external override onlyFromFactoryOrModule { _addModule(_module, controller.moduleRegistry()); } function removeModule(address _module) external override onlyFromModule { // Allow deactivate to fail to make sure the module can be removed require(modules[_module], "MODULE_NOT_EXISTS"); try Module(_module).deactivate() {} catch {} delete modules[_module]; emit ModuleRemoved(_module); } function hasModule(address _module) public view override returns (bool) { return modules[_module]; } function bindMethod(bytes4 _method, address _module) external override onlyFromModule { require(_method != bytes4(0), "BAD_METHOD"); if (_module != address(0)) { require(modules[_module], "MODULE_UNAUTHORIZED"); } methodToModule[_method] = _module; emit MethodBound(_method, _module); } function boundMethodModule(bytes4 _method) public view override returns (address) { return methodToModule[_method]; } function transact( uint8 mode, address to, uint value, bytes calldata data ) external override onlyFromFactoryOrModule returns (bytes memory returnData) { bool success; (success, returnData) = _call(mode, to, value, data); if (!success) { assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } } receive() external payable { } /// @dev This default function can receive Ether or perform queries to modules /// using bound methods. fallback() external payable { address module = methodToModule[msg.sig]; require(modules[module], "MODULE_UNAUTHORIZED"); (bool success, bytes memory returnData) = module.call{value: msg.value}(msg.data); assembly { switch success case 0 { revert(add(returnData, 32), mload(returnData)) } default { return(add(returnData, 32), mload(returnData)) } } } function _addModule(address _module, ModuleRegistry moduleRegistry) internal { require(_module != address(0), "NULL_MODULE"); require(modules[_module] == false, "MODULE_EXISTS"); require( moduleRegistry.isModuleEnabled(_module), "INVALID_MODULE" ); modules[_module] = true; emit ModuleAdded(_module); Module(_module).activate(); } function _call( uint8 mode, address target, uint value, bytes calldata data ) private returns ( bool success, bytes memory returnData ) { if (mode == 1) { // solium-disable-next-line security/no-call-value (success, returnData) = target.call{value: value}(data); } else if (mode == 2) { // solium-disable-next-line security/no-call-value (success, returnData) = target.delegatecall(data); } else if (mode == 3) { require(value == 0, "INVALID_VALUE"); // solium-disable-next-line security/no-call-value (success, returnData) = target.staticcall(data); } else { revert("UNSUPPORTED_MODE"); } } } // File: contracts/modules/WalletImpl.sol // Copyright 2017 Loopring Technology Limited. /// @title WalletImpl contract WalletImpl is BaseWallet { function version() public override pure returns (string memory) { // 使用中国省会作为别名 return "1.2.0 (daqing)"; } }
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newController","type":"address"}],"name":"ControllerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes4","name":"method","type":"bytes4"},{"indexed":false,"internalType":"address","name":"module","type":"address"}],"name":"MethodBound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"module","type":"address"}],"name":"ModuleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"module","type":"address"}],"name":"ModuleRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"WalletSetup","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_module","type":"address"}],"name":"addModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_method","type":"bytes4"},{"internalType":"address","name":"_module","type":"address"}],"name":"bindMethod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_method","type":"bytes4"}],"name":"boundMethodModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract Controller","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_module","type":"address"}],"name":"hasModule","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract Controller","name":"_controller","type":"address"},{"internalType":"address[]","name":"_modules","type":"address[]"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_initialOwner","type":"address"}],"name":"initOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_module","type":"address"}],"name":"removeModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Controller","name":"newController","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"mode","type":"uint8"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"transact","outputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"stateMutability":"payable","type":"receive"}]
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.998411 | 128.2213 | $128.02 |
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.