ETH Price: $2,626.53 (+4.57%)
Gas: 0.96 Gwei

Transaction Decoder

Block:
12818225 at Jul-13-2021 10:20:14 AM +UTC
Transaction Fee:
0.00082485 ETH $2.17
Gas Used:
63,450 Gas / 13 Gwei

Emitted Events:

357 ZildFinanceCoin.Transfer( from=[Receiver] PledgeDeposit, to=[Sender] 0xedd12ce845a2a5145f05e936c0b04b4adffee71c, value=300000000000000000 )
358 PledgeDeposit.Withdraw( userAddress=[Sender] 0xedd12ce845a2a5145f05e936c0b04b4adffee71c, userOrderId=1, poolId=1, symbol=ZILD, depositId=0, depositAmount=250000000000000000, pledgeAmount=50000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x006699d3...59A16B12B
(Miner: 0xc8F...7C9)
9,699.915255708853377906 Eth9,699.916080558853377906 Eth0.00082485
0xEdd12CE8...ADfFEe71C
0.01022184704 Eth
Nonce: 2
0.00939699704 Eth
Nonce: 3
0.00082485
0xF7686CF0...A0C3A28F3
(ZILD: Pledge Deposit)

Execution Trace

PledgeDeposit.withdraw( _poolId=1, _depositId=0 )
  • ZildFinanceCoin.transfer( to=0xEdd12CE845A2a5145f05E936c0b04b4ADfFEe71C, amount=300000000000000000 ) => ( True )
    File 1 of 2: PledgeDeposit
    pragma solidity 0.6.12;
    
    
    // File: @openzeppelin/contracts/token/ERC20/IERC20.sol
    /**
     * @dev Interface of the ERC20 , add some function for gToken and cToken
     */
    interface IERC20 {
        /**
         * @dev Returns the amount of tokens in existence.
         */
        function totalSupply() external view returns (uint256);
    
        /**
         * @dev Returns the amount of tokens owned by `account`.
         */
        function balanceOf(address account) external view returns (uint256);
    
        /**
         * @dev Moves `amount` tokens from the caller's account to `recipient`.
         *
         * Returns a boolean value indicating whether the operation succeeded.
         *
         * Emits a {Transfer} event.
         */
        function transfer(address recipient, uint256 amount) external returns (bool);
    
        /**
         * @dev Returns the remaining number of tokens that `spender` will be
         * allowed to spend on behalf of `owner` through {transferFrom}. This is
         * zero by default.
         *
         * This value changes when {approve} or {transferFrom} are called.
         */
        function allowance(address owner, address spender) external view returns (uint256);
    
        /**
         * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
         *
         * Returns a boolean value indicating whether the operation succeeded.
         *
         * IMPORTANT: Beware that changing an allowance with this method brings the risk
         * that someone may use both the old and the new allowance by unfortunate
         * transaction ordering. One possible solution to mitigate this race
         * condition is to first reduce the spender's allowance to 0 and set the
         * desired value afterwards:
         * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
         *
         * Emits an {Approval} event.
         */
        function approve(address spender, uint256 amount) external returns (bool);
    
        /**
         * @dev Moves `amount` tokens from `sender` to `recipient` using the
         * allowance mechanism. `amount` is then deducted from the caller's
         * allowance.
         *
         * Returns a boolean value indicating whether the operation succeeded.
         *
         * Emits a {Transfer} event.
         */
        function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    
        /**
         * @dev Emitted when `value` tokens are moved from one account (`from`) to
         * another (`to`).
         *
         * Note that `value` may be zero.
         */
        event Transfer(address indexed from, address indexed to, uint256 value);
    
        /**
         * @dev Emitted when the allowance of a `spender` for an `owner` is set by
         * a call to {approve}. `value` is the new allowance.
         */
        event Approval(address indexed owner, address indexed spender, uint256 value);
    
    
    }
    
    
    library SafeMath {
    
        function add(uint256 a, uint256 b) internal pure returns (uint256) {
            uint256 c = a + b;
            require(c >= a, "SafeMath: addition overflow");
    
            return c;
        }
    
        function sub(uint256 a, uint256 b) internal pure returns (uint256) {
            return sub(a, b, "SafeMath: subtraction overflow");
        }
    
        function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
            require(b <= a, errorMessage);
            uint256 c = a - b;
    
            return c;
        }
    
        function mul(uint256 a, uint256 b) internal pure returns (uint256) {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) {
                return 0;
            }
    
            uint256 c = a * b;
            require(c / a == b, "SafeMath: multiplication overflow");
    
            return c;
        }
    
        function div(uint256 a, uint256 b) internal pure returns (uint256) {
            return div(a, b, "SafeMath: division by zero");
        }
    
        function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
            require(b > 0, errorMessage);
            uint256 c = a / b;
            // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    
            return c;
        }
    
        function mod(uint256 a, uint256 b) internal pure returns (uint256) {
            return mod(a, b, "SafeMath: modulo by zero");
        }
    
       function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
            require(b != 0, errorMessage);
            return a % b;
        }
    }
    
    
    // File: @openzeppelin/contracts/utils/Address.sol
    
    
    
    /**
     * @dev Collection of functions related to the address type
     */
    library Address {
        /**
         * @dev Returns true if `account` is a contract.
         *
         * [IMPORTANT]
         * ====
         * It is unsafe to assume that an address for which this function returns
         * false is an externally-owned account (EOA) and not a contract.
         *
         * Among others, `isContract` will return false for the following
         * types of addresses:
         *
         *  - an externally-owned account
         *  - a contract in construction
         *  - an address where a contract will be created
         *  - an address where a contract lived, but was destroyed
         * ====
         */
        function isContract(address account) internal view returns (bool) {
            // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
            // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
            // for accounts without code, i.e. `keccak256('')`
            bytes32 codehash;
            bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
            // solhint-disable-next-line no-inline-assembly
            assembly { codehash := extcodehash(account) }
            return (codehash != accountHash && codehash != 0x0);
        }
    
        /**
         * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
         * `recipient`, forwarding all available gas and reverting on errors.
         *
         * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
         * of certain opcodes, possibly making contracts go over the 2300 gas limit
         * imposed by `transfer`, making them unable to receive funds via
         * `transfer`. {sendValue} removes this limitation.
         *
         * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
         *
         * IMPORTANT: because control is transferred to `recipient`, care must be
         * taken to not create reentrancy vulnerabilities. Consider using
         * {ReentrancyGuard} or the
         * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
         */
        function sendValue(address payable recipient, uint256 amount) internal {
            require(address(this).balance >= amount, "Address: insufficient balance");
    
            // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
            (bool success, ) = recipient.call{ value: amount }("");
            require(success, "Address: unable to send value, recipient may have reverted");
        }
    
        /**
         * @dev Performs a Solidity function call using a low level `call`. A
         * plain`call` is an unsafe replacement for a function call: use this
         * function instead.
         *
         * If `target` reverts with a revert reason, it is bubbled up by this
         * function (like regular Solidity function calls).
         *
         * Returns the raw returned data. To convert to the expected return value,
         * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
         *
         * Requirements:
         *
         * - `target` must be a contract.
         * - calling `target` with `data` must not revert.
         *
         * _Available since v3.1._
         */
        function functionCall(address target, bytes memory data) internal returns (bytes memory) {
          return functionCall(target, data, "Address: low-level call failed");
        }
    
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
         * `errorMessage` as a fallback revert reason when `target` reverts.
         *
         * _Available since v3.1._
         */
        function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
            return _functionCallWithValue(target, data, 0, errorMessage);
        }
    
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
         * but also transferring `value` wei to `target`.
         *
         * Requirements:
         *
         * - the calling contract must have an ETH balance of at least `value`.
         * - the called Solidity function must be `payable`.
         *
         * _Available since v3.1._
         */
        function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
            return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
        }
    
        /**
         * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
         * with `errorMessage` as a fallback revert reason when `target` reverts.
         *
         * _Available since v3.1._
         */
        function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
            require(address(this).balance >= value, "Address: insufficient balance for call");
            return _functionCallWithValue(target, data, value, errorMessage);
        }
    
        function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
            require(isContract(target), "Address: call to non-contract");
    
            // solhint-disable-next-line avoid-low-level-calls
            (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
            if (success) {
                return returndata;
            } else {
                // Look for revert reason and bubble it up if present
                if (returndata.length > 0) {
                    // The easiest way to bubble the revert reason is using memory via assembly
    
                    // solhint-disable-next-line no-inline-assembly
                    assembly {
                        let returndata_size := mload(returndata)
                        revert(add(32, returndata), returndata_size)
                    }
                } else {
                    revert(errorMessage);
                }
            }
        }
    }
    
    // File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol
    
    
    
    
    
    
    
    /**
     * @title SafeERC20
     * @dev Wrappers around ERC20 operations that throw on failure (when the token
     * contract returns false). Tokens that return no value (and instead revert or
     * throw on failure) are also supported, non-reverting calls are assumed to be
     * successful.
     * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
     * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
     */
    library SafeERC20 {
        using SafeMath for uint256;
        using Address for address;
    
        function safeTransfer(IERC20 token, address to, uint256 value) internal {
            _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
        }
    
        function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
            _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
        }
    
        /**
         * @dev Deprecated. This function has issues similar to the ones found in
         * {IERC20-approve}, and its usage is discouraged.
         *
         * Whenever possible, use {safeIncreaseAllowance} and
         * {safeDecreaseAllowance} instead.
         */
        function safeApprove(IERC20 token, address spender, uint256 value) internal {
            // safeApprove should only be called when setting an initial allowance,
            // or when resetting it to zero. To increase and decrease it, use
            // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
            // solhint-disable-next-line max-line-length
            require((value == 0) || (token.allowance(address(this), spender) == 0),
                "SafeERC20: approve from non-zero to non-zero allowance"
            );
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
        }
    
        function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
            uint256 newAllowance = token.allowance(address(this), spender).add(value);
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    
        function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
            uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    
        /**
         * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
         * on the return value: the return value is optional (but if data is returned, it must not be false).
         * @param token The token targeted by the call.
         * @param data The call data (encoded using abi.encode or one of its variants).
         */
        function _callOptionalReturn(IERC20 token, bytes memory data) private {
            // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
            // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
            // the target address contains contract code and also asserts for success in the low-level call.
    
            bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
            if (returndata.length > 0) { // Return data is optional
                // solhint-disable-next-line max-line-length
                require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
            }
        }
    }
    
    
    
    contract Ownable {
        address public owner;
        address public newowner;
        address public admin;
        address public dev;
    
        constructor() public {
            owner = msg.sender;
        }
    
        modifier onlyOwner {
            require(msg.sender == owner);
            _;
        }
    
        modifier onlyNewOwner {
            require(msg.sender == newowner);
            _;
        }
        
        function transferOwnership(address _newOwner) public onlyOwner {
            newowner = _newOwner;
        }
        
        function takeOwnership() public onlyNewOwner {
            owner = newowner;
        }    
        
        function setAdmin(address _admin) public onlyOwner {
            admin = _admin;
        }
        
        function setDev(address _dev) public onlyOwner {
            dev = _dev;
        }
        
        modifier onlyAdmin {
            require(msg.sender == admin || msg.sender == owner);
            _;
        }
    
        modifier onlyDev {
            require(msg.sender == dev || msg.sender == admin || msg.sender == owner);
            _;
        }    
    }
    
    
    contract PledgeDeposit is Ownable{
    
        using SafeMath for uint256;
        using SafeERC20 for IERC20;
    
        
        struct PoolInfo {
            IERC20 token;
            string symbol;
        }
    
        struct DepositInfo {
            uint256 userOrderId;
            uint256 depositAmount;
            uint256 pledgeAmount;
            uint256 depositTime;
            uint256 depositBlock;
            uint256 expireBlock;
        }
        
    
        IERC20 public zild;
    
        /**
         * @dev  Guard variable for re-entrancy checks
         */
        bool internal _notEntered;
    
        uint256 public minDepositBlock = 1;
    
     
        PoolInfo[] public poolArray;
    
    
        // poolId , user address, DepositInfo
        mapping (uint256 => mapping (address => DepositInfo[])) public userDepositMap;
    
        mapping (address => uint256) public lastUserOrderIdMap;
    
        uint256 public pledgeBalance;    
    
        event NewPool(address addr, string symbol);
    
        event UpdateMinDepositBlock(uint256 dblock,address  who,uint256 time);
    
        event ZildBurnDeposit(address  userAddress,uint256 userOrderId, uint256 burnAmount);
        event Deposit(address  userAddress,uint256 userOrderId, uint256 poolId,string symbol,uint256 depositId, uint256 depositAmount,uint256 pledgeAmount);
        event Withdraw(address  userAddress,uint256 userOrderId, uint256 poolId,string symbol,uint256 depositId, uint256 depositAmount,uint256 pledgeAmount);
        
        constructor(address _zild,address _usdt) public {
            zild = IERC20(_zild);
    
            // poolArray[0] :  ETH 
            addPool(address(0),'ETH');  
    
            // poolArray[1] : ZILD  
            addPool(_zild,'ZILD');  
    
            // poolArray[2] : USDT  
            addPool(_usdt,'USDT');  
    
            _notEntered = true;
      
        }
    
            /*** Reentrancy Guard ***/
    
        /**
         * Prevents a contract from calling itself, directly or indirectly.
         */
        modifier nonReentrant() {
            require(_notEntered, "re-entered");
            _notEntered = false;
            _;
            _notEntered = true; // get a gas-refund post-Istanbul
        }
        
    
        function addPool(address  _token, string memory _symbol) public onlyAdmin {
            poolArray.push(PoolInfo({token: IERC20(_token),symbol: _symbol}));
            emit NewPool(_token, _symbol);
        }
    
        function poolLength() external view returns (uint256) {
            return poolArray.length;
        }
    
        function updateMinDepositBlock(uint256 _minDepositBlock) public onlyAdmin {
            require(_minDepositBlock > 0,"Desposit: New deposit time must be greater than 0");
            minDepositBlock = _minDepositBlock;
            emit UpdateMinDepositBlock(minDepositBlock,msg.sender,now);
        }
          
        function tokenDepositCount(address _user, uint256 _poolId)  view public returns(uint256) {
            require(_poolId < poolArray.length, "invalid _poolId");
            return userDepositMap[_poolId][_user].length;
        }
    
        function burnDeposit(uint256 _userOrderId, uint256 _burnAmount) public{
           require(_userOrderId > lastUserOrderIdMap[msg.sender], "_userOrderId should greater than lastUserOrderIdMap[msg.sender]");
           
           lastUserOrderIdMap[msg.sender]  = _userOrderId;
           
           zild.transferFrom(address(msg.sender), address(1024), _burnAmount);       
      
           emit ZildBurnDeposit(msg.sender, _userOrderId, _burnAmount);
        }
    
        function deposit(uint256 _userOrderId, uint256 _poolId, uint256 _depositAmount,uint256 _pledgeAmount) public nonReentrant  payable{
           require(_poolId < poolArray.length, "invalid _poolId");
           require(_userOrderId > lastUserOrderIdMap[msg.sender], "_userOrderId should greater than lastUserOrderIdMap[msg.sender]");
           
           lastUserOrderIdMap[msg.sender]  = _userOrderId;
           PoolInfo storage poolInfo = poolArray[_poolId];
    
           // ETH
           if(_poolId == 0){
                require(_depositAmount == msg.value, "invald  _depositAmount for ETH");
                zild.safeTransferFrom(address(msg.sender), address(this), _pledgeAmount);
           }
           // ZILD
           else if(_poolId == 1){
                uint256 zildAmount = _pledgeAmount.add(_depositAmount);
                zild.safeTransferFrom(address(msg.sender), address(this), zildAmount);
           }
           else{
                zild.safeTransferFrom(address(msg.sender), address(this), _pledgeAmount);
                poolInfo.token.safeTransferFrom(address(msg.sender), address(this), _depositAmount);
           }
    
           pledgeBalance = pledgeBalance.add(_pledgeAmount);
    
           uint256 depositId = userDepositMap[_poolId][msg.sender].length;
           userDepositMap[_poolId][msg.sender].push(
                DepositInfo({
                    userOrderId: _userOrderId,
                    depositAmount: _depositAmount,
                    pledgeAmount: _pledgeAmount,
                    depositTime: now,
                    depositBlock: block.number,
                    expireBlock: block.number.add(minDepositBlock)
                })
            );
        
            emit Deposit(msg.sender, _userOrderId, _poolId, poolInfo.symbol, depositId, _depositAmount, _pledgeAmount);
        }
    
        function getUserDepositInfo(address _user, uint256 _poolId,uint256 _depositId) public view returns (
            uint256 _userOrderId, uint256 _depositAmount,uint256 _pledgeAmount,uint256 _depositTime,uint256 _depositBlock,uint256 _expireBlock) {
            require(_poolId < poolArray.length, "invalid _poolId");
            require(_depositId < userDepositMap[_poolId][_user].length, "invalid _depositId");
    
            DepositInfo memory depositInfo = userDepositMap[_poolId][_user][_depositId];
            
            _userOrderId = depositInfo.userOrderId;
            _depositAmount = depositInfo.depositAmount;
            _pledgeAmount = depositInfo.pledgeAmount;
            _depositTime = depositInfo.depositTime;
            _depositBlock = depositInfo.depositBlock;
            _expireBlock = depositInfo.expireBlock;
        }
    
        function withdraw(uint256 _poolId,uint256 _depositId) public nonReentrant {
            require(_poolId < poolArray.length, "invalid _poolId");
            require(_depositId < userDepositMap[_poolId][msg.sender].length, "invalid _depositId");
    
            PoolInfo storage poolInfo = poolArray[_poolId];
            DepositInfo storage depositInfo = userDepositMap[_poolId][msg.sender][_depositId];
    
            require(block.number > depositInfo.expireBlock, "The withdrawal block has not arrived");
            uint256 depositAmount =  depositInfo.depositAmount;
            require( depositAmount > 0, "There is no deposit available!");
    
            uint256 pledgeAmount = depositInfo.pledgeAmount;
    
            pledgeBalance = pledgeBalance.sub(pledgeAmount);
            depositInfo.depositAmount =  0;    
            depositInfo.pledgeAmount = 0;
    
            // ETH
            if(_poolId == 0) {
                msg.sender.transfer(depositAmount);
                zild.safeTransfer(msg.sender,pledgeAmount);
            }
            // ZILD
            else if(_poolId == 1){
                zild.safeTransfer(msg.sender, depositAmount.add(pledgeAmount));
            }
            else{
                poolInfo.token.safeTransfer(msg.sender, depositAmount);
                zild.safeTransfer(msg.sender,pledgeAmount);
            }   
          
            emit Withdraw(msg.sender, depositInfo.userOrderId, _poolId, poolInfo.symbol, _depositId, depositAmount, pledgeAmount);
          }
    }

    File 2 of 2: ZildFinanceCoin
    {"IERC20.sol":{"content":"pragma solidity 0.5.4;\r\n\r\ninterface IERC20 {\r\n\r\n    function balanceOf(address account) external view returns (uint256);\r\n    function transfer(address recipient, uint256 amount) external returns (bool);\r\n    function allowance(address owner, address spender) external view returns (uint256);\r\n    function approve(address spender, uint256 amount) external returns (bool);\r\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\r\n    event Transfer(address indexed from, address indexed to, uint256 value);\r\n    event Approval(address indexed owner, address indexed spender, uint256 value);\r\n\r\n}"},"Ownable.sol":{"content":"pragma solidity 0.5.4;\r\n\r\ncontract Ownable {\r\n\r\n    address private _owner;\r\n\r\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r\n\r\n    constructor() internal {\r\n        _owner = msg.sender;\r\n        emit OwnershipTransferred(address(0), _owner);\r\n    }\r\n\r\n    function owner() public view returns (address) {\r\n        return _owner;\r\n    }\r\n\r\n    function isOwner() public view returns (bool) {\r\n        return msg.sender == _owner;\r\n    }\r\n\r\n    modifier onlyOwner() {\r\n        require(msg.sender == _owner, \"Ownable: caller is not the owner\");\r\n        _;\r\n    }\r\n\r\n    function transferOwnership(address newOwner) public onlyOwner {\r\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\r\n        emit OwnershipTransferred(_owner, newOwner);\r\n        _owner = newOwner;\r\n    }\r\n\r\n}"},"SafeMath.sol":{"content":"pragma solidity ^0.5.0;\r\n\r\n/**\r\n * @dev Wrappers over Solidity\u0027s arithmetic operations with added overflow\r\n * checks.\r\n *\r\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\r\n * in bugs, because programmers usually assume that an overflow raises an\r\n * error, which is the standard behavior in high level programming languages.\r\n * `SafeMath` restores this intuition by reverting the transaction when an\r\n * operation overflows.\r\n *\r\n * Using this library instead of the unchecked operations eliminates an entire\r\n * class of bugs, so it\u0027s recommended to use it always.\r\n */\r\nlibrary SafeMath {\r\n    /**\r\n     * @dev Returns the addition of two unsigned integers, reverting on\r\n     * overflow.\r\n     *\r\n     * Counterpart to Solidity\u0027s `+` operator.\r\n     *\r\n     * Requirements:\r\n     * - Addition cannot overflow.\r\n     */\r\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\r\n        uint256 c = a + b;\r\n        require(c \u003e= a, \"SafeMath: addition overflow\");\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the subtraction of two unsigned integers, reverting on\r\n     * overflow (when the result is negative).\r\n     *\r\n     * Counterpart to Solidity\u0027s `-` operator.\r\n     *\r\n     * Requirements:\r\n     * - Subtraction cannot overflow.\r\n     */\r\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\r\n        return sub(a, b, \"SafeMath: subtraction overflow\");\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\r\n     * overflow (when the result is negative).\r\n     *\r\n     * Counterpart to Solidity\u0027s `-` operator.\r\n     *\r\n     * Requirements:\r\n     * - Subtraction cannot overflow.\r\n     *\r\n     * _Available since v2.4.0._\r\n     */\r\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\r\n        require(b \u003c= a, errorMessage);\r\n        uint256 c = a - b;\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the multiplication of two unsigned integers, reverting on\r\n     * overflow.\r\n     *\r\n     * Counterpart to Solidity\u0027s `*` operator.\r\n     *\r\n     * Requirements:\r\n     * - Multiplication cannot overflow.\r\n     */\r\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\r\n        // Gas optimization: this is cheaper than requiring \u0027a\u0027 not being zero, but the\r\n        // benefit is lost if \u0027b\u0027 is also tested.\r\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\r\n        if (a == 0) {\r\n            return 0;\r\n        }\r\n\r\n        uint256 c = a * b;\r\n        require(c / a == b, \"SafeMath: multiplication overflow\");\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the integer division of two unsigned integers. Reverts on\r\n     * division by zero. The result is rounded towards zero.\r\n     *\r\n     * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\r\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n     * uses an invalid opcode to revert (consuming all remaining gas).\r\n     *\r\n     * Requirements:\r\n     * - The divisor cannot be zero.\r\n     */\r\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\r\n        return div(a, b, \"SafeMath: division by zero\");\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\r\n     * division by zero. The result is rounded towards zero.\r\n     *\r\n     * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\r\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n     * uses an invalid opcode to revert (consuming all remaining gas).\r\n     *\r\n     * Requirements:\r\n     * - The divisor cannot be zero.\r\n     *\r\n     * _Available since v2.4.0._\r\n     */\r\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\r\n        // Solidity only automatically asserts when dividing by 0\r\n        require(b \u003e 0, errorMessage);\r\n        uint256 c = a / b;\r\n        // assert(a == b * c + a % b); // There is no case in which this doesn\u0027t hold\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\r\n     * Reverts when dividing by zero.\r\n     *\r\n     * Counterpart to Solidity\u0027s `%` operator. This function uses a `revert`\r\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\r\n     * invalid opcode to revert (consuming all remaining gas).\r\n     *\r\n     * Requirements:\r\n     * - The divisor cannot be zero.\r\n     */\r\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\r\n        return mod(a, b, \"SafeMath: modulo by zero\");\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\r\n     * Reverts with custom message when dividing by zero.\r\n     *\r\n     * Counterpart to Solidity\u0027s `%` operator. This function uses a `revert`\r\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\r\n     * invalid opcode to revert (consuming all remaining gas).\r\n     *\r\n     * Requirements:\r\n     * - The divisor cannot be zero.\r\n     *\r\n     * _Available since v2.4.0._\r\n     */\r\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\r\n        require(b != 0, errorMessage);\r\n        return a % b;\r\n    }\r\n}"},"ZildFinance.sol":{"content":"pragma solidity 0.5.4;\r\n\r\nimport \u0027SafeMath.sol\u0027;\r\nimport \u0027Ownable.sol\u0027;\r\nimport \u0027IERC20.sol\u0027;\r\n\r\ncontract ZildFinanceCoin is Ownable, IERC20 {\r\n\r\n    using SafeMath for uint256;\r\n\r\n    string public constant name = \u0027Zild Finance Coin\u0027;\r\n    string public constant symbol = \u0027Zild\u0027;\r\n    uint8 public constant decimals = 18;\r\n    uint256 public totalSupply = 9980 * 10000 * 10 ** uint256(decimals);\r\n    uint256 public allowBurn = 2100 * 10000 * 10 ** uint256(decimals);\r\n    uint256 public tokenDestroyed;\r\n\t\r\n    uint256 public constant FounderAllocation = 1497 * 10000 * 10 ** uint256(decimals);\r\n    uint256 public constant FounderLockupAmount = 998 * 10000 * 10 ** uint256(decimals);\r\n    uint256 public constant FounderLockupCliff = 365 days;\r\n    uint256 public constant FounderReleaseInterval = 30 days;\r\n    uint256 public constant FounderReleaseAmount = 20.7916 * 10000 * 10 ** uint256(decimals);\r\n    uint256 public constant MarketingAllocation = 349 * 10000 * 10 ** uint256(decimals);\r\n    uint256 public constant FurnaceAllocation = 150 * 10000 * 10 ** uint256(decimals);\r\n\t\r\n    address public founder = address(0);\r\n    uint256 public founderLockupStartTime = 0;\r\n    uint256 public founderReleasedAmount = 0;\r\n\r\n    mapping (address =\u003e uint256) private _balances;\r\n    mapping (address =\u003e mapping (address =\u003e uint256)) private _allowances;    \r\n    mapping (address =\u003e bool) public frozenAccount;\r\n\r\n    event Transfer(address indexed from, address indexed to, uint256 value);\r\n    event Approval(address indexed from, address indexed to, uint256 value);\r\n    event ChangeFounder(address indexed previousFounder, address indexed newFounder);\r\n    event SetMinter(address indexed minter);\r\n    event SetMarketing(address indexed marketing);\r\n    event SetFurnace(address indexed furnace);\t\r\n    event Burn(address indexed _from, uint256 _tokenDestroyed, uint256 _timestamp);\r\n    event FrozenFunds(address target, bool frozen);\r\n\t\r\n    constructor(address _founder, address _marketing) public {\r\n        require(_founder != address(0), \"ZildFinanceCoin: founder is the zero address\");\r\n        require(_marketing != address(0), \"ZildFinanceCoin: operator is the zero address\");\r\n        founder = _founder;\r\n        founderLockupStartTime = block.timestamp;\r\n        _balances[address(this)] = totalSupply;\r\n        _transfer(address(this), _marketing, MarketingAllocation);\r\n    }\r\n\r\n    function release() public {\r\n        uint256 currentTime = block.timestamp;\r\n        uint256 cliffTime = founderLockupStartTime.add(FounderLockupCliff);\r\n        if (currentTime \u003c cliffTime) return;\r\n        if (founderReleasedAmount \u003e= FounderLockupAmount) return;\r\n        uint256 month = currentTime.sub(cliffTime).div(FounderReleaseInterval);\r\n        uint256 releaseAmount = month.mul(FounderReleaseAmount);\r\n        if (releaseAmount \u003e FounderLockupAmount) releaseAmount = FounderLockupAmount;\r\n        if (releaseAmount \u003c= founderReleasedAmount) return;\r\n        uint256 amount = releaseAmount.sub(founderReleasedAmount);\r\n        founderReleasedAmount = releaseAmount;\r\n        _transfer(address(this), founder, amount);\r\n    }\r\n\r\n    function balanceOf(address account) public view returns (uint256) {\r\n        return _balances[account];\r\n    }\r\n\r\n    function transfer(address to, uint256 amount) public returns (bool) {\r\n        require(to != address(0), \"ERC20: tranfer to the zero address\");\r\n        require(!frozenAccount[msg.sender]);\r\n        require(!frozenAccount[to]);\r\n        _transfer(msg.sender, to, amount);\r\n        return true;\r\n    }\r\n\t\r\n    function burn(uint256 _value) public returns (bool){\r\n        _burn(msg.sender, _value);\r\n        return true;\r\n    }\r\n\r\n    function _burn(address _who, uint256 _burntAmount) internal {\r\n        require (tokenDestroyed.add(_burntAmount) \u003c= allowBurn, \"ZildFinanceCoin: exceeded the maximum allowable burning amount\" );\r\n        require(_balances[msg.sender] \u003e= _burntAmount \u0026\u0026 _burntAmount \u003e 0);\r\n        _transfer(address(_who), address(0), _burntAmount);\r\n        totalSupply = totalSupply.sub(_burntAmount);\r\n        tokenDestroyed = tokenDestroyed.add(_burntAmount);\r\n        emit Burn(_who, _burntAmount, block.timestamp);\r\n    }\r\n\t\r\n\r\n    function allowance(address from, address to) public view returns (uint256) {\r\n        return _allowances[from][to];\r\n    }\r\n\r\n    function approve(address to, uint256 amount) public returns (bool) {\r\n        _approve(msg.sender, to, amount);\r\n        return true;\r\n    }\r\n\r\n    function transferFrom(address from, address to, uint256 amount) public returns (bool) {\r\n        uint256 remaining = _allowances[from][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\");\r\n        require(to != address(0), \"ERC20: tranfer to the zero address\");\r\n        require(!frozenAccount[from]);\r\n        require(!frozenAccount[to]);\r\n        require(!frozenAccount[msg.sender]);\r\n        _transfer(from, to, amount);\r\n        _approve(from, msg.sender, remaining);\r\n        return true;\r\n    }\r\n\r\n    function _transfer(address from, address to, uint256 amount) private {\r\n        require(from != address(0), \"ERC20: transfer from the zero address\");\r\n        _balances[from] = _balances[from].sub(amount, \"ERC20: transfer amount exceeds balance\");\r\n        _balances[to] = _balances[to].add(amount);\r\n        emit Transfer(from, to, amount);\r\n    }\r\n\r\n    function _approve(address from, address to, uint256 amount) private {\r\n        require(from != address(0), \"ERC20: approve from the zero address\");\r\n        require(to != address(0), \"ERC20: approve to the zero address\");\r\n        _allowances[from][to] = amount;\r\n        emit Approval(from, to, amount);\r\n    }\r\n\r\n    function changeFounder(address _founder) public onlyOwner {\r\n        require(_founder != address(0), \"ZildFinanceCoin: founder is the zero address\");\r\n        emit ChangeFounder(founder, _founder);\r\n        founder = _founder;\r\n    }\r\n\r\n    function setMinter(address minter) public onlyOwner {\r\n        require(minter != address(0), \"ZildFinanceCoin: minter is the zero address\");\r\n        require(_balances[minter] == 0, \"ZildFinanceCoin: minter has been initialized\");\r\n        _transfer(address(this), minter, totalSupply.sub(FounderAllocation));\r\n        emit SetMinter(minter);\r\n    }\r\n\r\n    function setFurnace(address furnace) public onlyOwner {\r\n        require(furnace != address(0), \"ZildFinanceCoin: furnace is the zero address\");\r\n        require(_balances[furnace] == 0, \"ZildFinanceCoin: furnace has been initialized\");\r\n        _transfer(address(this), furnace, FurnaceAllocation);\r\n        emit SetFurnace(furnace);\r\n    }\r\n\t\r\n    function freezeAccount(address _target, bool _bool) public onlyOwner {\r\n        if (_target != address(0)) {\r\n            frozenAccount[_target] = _bool;\r\n            emit FrozenFunds(_target,_bool);\r\n        }\r\n    }\r\n\r\n}"}}