Transaction Hash:
Block:
11704651 at Jan-22-2021 10:03:11 AM +UTC
Transaction Fee:
0.08333896 ETH
$203.71
Gas Used:
1,041,737 Gas / 80 Gwei
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x00192Fb1...d1BF599E8
Miner
| (2Miners: PPLNS) | 359.32282455555343282 Eth | 359.40616351555343282 Eth | 0.08333896 | |
0x16CC37d0...AbB396A2b |
2.0102096 Eth
Nonce: 14
|
1.92687064 Eth
Nonce: 15
| 0.08333896 | ||
0x72d220cE...AD8598f6C | (DODO: Vending Machine Factory) |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
|
Execution Trace
DVMFactory.60e06040( )
// File: contracts/lib/InitializableOwnable.sol /* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; /** * @title Ownable * @author DODO Breeder * * @notice Ownership related functions */ contract InitializableOwnable { address public _OWNER_; address public _NEW_OWNER_; bool internal _INITIALIZED_; // ============ Events ============ event OwnershipTransferPrepared(address indexed previousOwner, address indexed newOwner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); // ============ Modifiers ============ modifier notInitialized() { require(!_INITIALIZED_, "DODO_INITIALIZED"); _; } modifier onlyOwner() { require(msg.sender == _OWNER_, "NOT_OWNER"); _; } // ============ Functions ============ function initOwner(address newOwner) public notInitialized { _INITIALIZED_ = true; _OWNER_ = newOwner; } function transferOwnership(address newOwner) public onlyOwner { emit OwnershipTransferPrepared(_OWNER_, newOwner); _NEW_OWNER_ = newOwner; } function claimOwnership() public { require(msg.sender == _NEW_OWNER_, "INVALID_CLAIM"); emit OwnershipTransferred(_OWNER_, _NEW_OWNER_); _OWNER_ = _NEW_OWNER_; _NEW_OWNER_ = address(0); } } // File: contracts/lib/CloneFactory.sol interface ICloneFactory { function clone(address prototype) external returns (address proxy); } // introduction of proxy mode design: https://docs.openzeppelin.com/upgrades/2.8/ // minimum implementation of transparent proxy: https://eips.ethereum.org/EIPS/eip-1167 contract CloneFactory is ICloneFactory { function clone(address prototype) external override returns (address proxy) { bytes20 targetBytes = bytes20(prototype); assembly { let clone := mload(0x40) mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(clone, 0x14), targetBytes) mstore( add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000 ) proxy := create(0, clone, 0x37) } return proxy; } } // File: contracts/DODOVendingMachine/intf/IDVM.sol interface IDVM { function init( address maintainer, address baseTokenAddress, address quoteTokenAddress, uint256 lpFeeRate, address mtFeeRateModel, uint256 i, uint256 k, bool isOpenTWAP ) external; function _BASE_TOKEN_() external returns (address); function _QUOTE_TOKEN_() external returns (address); function _MT_FEE_RATE_MODEL_() external returns (address); function getVaultReserve() external returns (uint256 baseReserve, uint256 quoteReserve); function sellBase(address to) external returns (uint256); function sellQuote(address to) external returns (uint256); function buyShares(address to) external returns (uint256); } // File: contracts/Factory/DVMFactory.sol interface IDVMFactory { function createDODOVendingMachine( address baseToken, address quoteToken, uint256 lpFeeRate, uint256 i, uint256 k, bool isOpenTWAP ) external returns (address newVendingMachine); } /** * @title DODO VendingMachine Factory * @author DODO Breeder * * @notice Create And Register DVM Pools */ contract DVMFactory is InitializableOwnable { // ============ Templates ============ address public immutable _CLONE_FACTORY_; address public immutable _DEFAULT_MAINTAINER_; address public immutable _DEFAULT_MT_FEE_RATE_MODEL_; address public _DVM_TEMPLATE_; // ============ Registry ============ // base -> quote -> DVM address list mapping(address => mapping(address => address[])) public _REGISTRY_; // creator -> DVM address list mapping(address => address[]) public _USER_REGISTRY_; // ============ Events ============ event NewDVM( address baseToken, address quoteToken, address creator, address dvm ); event RemoveDVM(address dvm); // ============ Functions ============ constructor( address cloneFactory, address dvmTemplate, address defaultMaintainer, address defaultMtFeeRateModel ) public { _CLONE_FACTORY_ = cloneFactory; _DVM_TEMPLATE_ = dvmTemplate; _DEFAULT_MAINTAINER_ = defaultMaintainer; _DEFAULT_MT_FEE_RATE_MODEL_ = defaultMtFeeRateModel; } function createDODOVendingMachine( address baseToken, address quoteToken, uint256 lpFeeRate, uint256 i, uint256 k, bool isOpenTWAP ) external returns (address newVendingMachine) { newVendingMachine = ICloneFactory(_CLONE_FACTORY_).clone(_DVM_TEMPLATE_); { IDVM(newVendingMachine).init( _DEFAULT_MAINTAINER_, baseToken, quoteToken, lpFeeRate, _DEFAULT_MT_FEE_RATE_MODEL_, i, k, isOpenTWAP ); } _REGISTRY_[baseToken][quoteToken].push(newVendingMachine); _USER_REGISTRY_[tx.origin].push(newVendingMachine); emit NewDVM(baseToken, quoteToken, tx.origin, newVendingMachine); } // ============ Admin Operation Functions ============ function updateDvmTemplate(address _newDVMTemplate) external onlyOwner { _DVM_TEMPLATE_ = _newDVMTemplate; } function addPoolByAdmin( address creator, address baseToken, address quoteToken, address pool ) external onlyOwner { _REGISTRY_[baseToken][quoteToken].push(pool); _USER_REGISTRY_[creator].push(pool); emit NewDVM(baseToken, quoteToken, creator, pool); } function removePoolByAdmin( address creator, address baseToken, address quoteToken, address pool ) external onlyOwner { address[] memory registryList = _REGISTRY_[baseToken][quoteToken]; for (uint256 i = 0; i < registryList.length; i++) { if (registryList[i] == pool) { registryList[i] = registryList[registryList.length - 1]; break; } } _REGISTRY_[baseToken][quoteToken] = registryList; _REGISTRY_[baseToken][quoteToken].pop(); address[] memory userRegistryList = _USER_REGISTRY_[creator]; for (uint256 i = 0; i < userRegistryList.length; i++) { if (userRegistryList[i] == pool) { userRegistryList[i] = userRegistryList[userRegistryList.length - 1]; break; } } _USER_REGISTRY_[creator] = userRegistryList; _USER_REGISTRY_[creator].pop(); emit RemoveDVM(pool); } // ============ View Functions ============ function getDODOPool(address baseToken, address quoteToken) external view returns (address[] memory machines) { return _REGISTRY_[baseToken][quoteToken]; } function getDODOPoolBidirection(address token0, address token1) external view returns (address[] memory baseToken0Machines, address[] memory baseToken1Machines) { return (_REGISTRY_[token0][token1], _REGISTRY_[token1][token0]); } function getDODOPoolByUser(address user) external view returns (address[] memory machines) { return _USER_REGISTRY_[user]; } }