Contract 0x6EEE3497d91ED600646f4e31000329ef2e5d210E

 
Txn Hash
Block
From
To
Value
0x78add4536286f6e1cd9f4d4c1af757a78cd74f26bbe699c63fd08224bb2d413855326852018-04-30 14:58:151039 days 6 hrs agoLoopring: Deployer 1 IN  0x6eee3497d91ed600646f4e31000329ef2e5d210e0 Ether0.0001728486
0xf0c59cb1f773020ba2f54532f9c809a61a9bb093853e1e1b07354a9357b97b7845254862017-11-10 10:04:331210 days 11 hrs agoLoopring: Deployer 1 IN  Contract Creation0 Ether0.0089489610
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TokenTransferDelegate

Compiler Version
v0.4.18+commit.9cf6e910

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
/**
 *Submitted for verification at Etherscan.io on 2017-11-10
*/

/*
  Copyright 2017 Loopring Project Ltd (Loopring Foundation).
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
pragma solidity 0.4.18;
/// @title UintUtil
/// @author Daniel Wang - <[email protected]>
/// @dev uint utility functions
library MathUint {
    function mul(uint a, uint b) internal pure returns (uint c) {
        c = a * b;
        require(a == 0 || c / a == b);
    }
    function sub(uint a, uint b) internal pure returns (uint) {
        require(b <= a);
        return a - b;
    }
    function add(uint a, uint b) internal pure returns (uint c) {
        c = a + b;
        require(c >= a);
    }
    function tolerantSub(uint a, uint b) internal pure returns (uint c) {
        return (a >= b) ? a - b : 0;
    }
    /// @dev calculate the square of Coefficient of Variation (CV)
    /// https://en.wikipedia.org/wiki/Coefficient_of_variation
    function cvsquare(
        uint[] arr,
        uint scale
        )
        internal
        pure
        returns (uint)
    {
        uint len = arr.length;
        require(len > 1);
        require(scale > 0);
        uint avg = 0;
        for (uint i = 0; i < len; i++) {
            avg += arr[i];
        }
        avg = avg / len;
        if (avg == 0) {
            return 0;
        }
        uint cvs = 0;
        uint s = 0;
        for (i = 0; i < len; i++) {
            s = arr[i] > avg ? arr[i] - avg : avg - arr[i];
            cvs += mul(s, s);
        }
        return (mul(mul(cvs, scale) / avg, scale) / avg) / (len - 1);
    }
}
/*
  Copyright 2017 Loopring Project Ltd (Loopring Foundation).
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
/*
  Copyright 2017 Loopring Project Ltd (Loopring Foundation).
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
/// @title ERC20 interface
/// @dev see https://github.com/ethereum/EIPs/issues/20
contract ERC20 {
    uint public totalSupply;
	
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    function balanceOf(address who) view public returns (uint256);
    function allowance(address owner, address spender) view public returns (uint256);
    function transfer(address to, uint256 value) public returns (bool);
    function transferFrom(address from, address to, uint256 value) public returns (bool);
    function approve(address spender, uint256 value) public returns (bool);
}
/*
  Copyright 2017 Loopring Project Ltd (Loopring Foundation).
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
/// @title Ownable
/// @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;
    /// @dev The Ownable constructor sets the original `owner` of the contract
    ///      to the sender.
    function Ownable() public {
        owner = msg.sender;
    }
    /// @dev Throws if called by any account other than the owner.
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }
    /// @dev Allows the current owner to transfer control of the contract to a
    ///      newOwner.
    /// @param newOwner The address to transfer ownership to.
    function transferOwnership(address newOwner) onlyOwner public {
        if (newOwner != address(0)) {
            owner = newOwner;
        }
    }
}
/// @title TokenTransferDelegate - Acts as a middle man to transfer ERC20 tokens
/// on behalf of different versions of Loopring protocol to avoid ERC20
/// re-authorization.
/// @author Daniel Wang - <[email protected]>.
contract TokenTransferDelegate is Ownable {
    using MathUint for uint;
    ////////////////////////////////////////////////////////////////////////////
    /// Variables                                                            ///
    ////////////////////////////////////////////////////////////////////////////
    mapping(address => AddressInfo) private addressInfos;
    address public latestAddress;
    ////////////////////////////////////////////////////////////////////////////
    /// Structs                                                              ///
    ////////////////////////////////////////////////////////////////////////////
    struct AddressInfo {
        address previous;
        uint32  index;
        bool    authorized;
    }
    ////////////////////////////////////////////////////////////////////////////
    /// Modifiers                                                            ///
    ////////////////////////////////////////////////////////////////////////////
    modifier onlyAuthorized() {
        if (isAddressAuthorized(msg.sender) == false) {
            revert();
        }
        _;
    }
    ////////////////////////////////////////////////////////////////////////////
    /// Events                                                               ///
    ////////////////////////////////////////////////////////////////////////////
    event AddressAuthorized(address indexed addr, uint32 number);
    event AddressDeauthorized(address indexed addr, uint32 number);
    ////////////////////////////////////////////////////////////////////////////
    /// Public Functions                                                     ///
    ////////////////////////////////////////////////////////////////////////////
    /// @dev Add a Loopring protocol address.
    /// @param addr A loopring protocol address.
    function authorizeAddress(address addr)
        onlyOwner
        external
    {
        AddressInfo storage addrInfo = addressInfos[addr];
        if (addrInfo.index != 0) { // existing
            if (addrInfo.authorized == false) { // re-authorize
                addrInfo.authorized = true;
                AddressAuthorized(addr, addrInfo.index);
            }
        } else {
            address prev = latestAddress;
            if (prev == address(0)) {
                addrInfo.index = 1;
                addrInfo.authorized = true;
            } else {
                addrInfo.previous = prev;
                addrInfo.index = addressInfos[prev].index + 1;
            }
            addrInfo.authorized = true;
            latestAddress = addr;
            AddressAuthorized(addr, addrInfo.index);
        }
    }
    /// @dev Remove a Loopring protocol address.
    /// @param addr A loopring protocol address.
    function deauthorizeAddress(address addr)
        onlyOwner
        external
    {
        uint32 index = addressInfos[addr].index;
        if (index != 0) {
            addressInfos[addr].authorized = false;
            AddressDeauthorized(addr, index);
        }
    }
    function isAddressAuthorized(address addr)
        public
        view
        returns (bool)
    {
        return addressInfos[addr].authorized;
    }
    function getLatestAuthorizedAddresses(uint max)
        external
        view
        returns (address[] addresses)
    {
        addresses = new address[](max);
        address addr = latestAddress;
        AddressInfo memory addrInfo;
        uint count = 0;
        while (addr != address(0) && max < count) {
            addrInfo = addressInfos[addr];
            if (addrInfo.index == 0) {
                break;
            }
            addresses[count++] = addr;
            addr = addrInfo.previous;
        }
    }
    /// @dev Invoke ERC20 transferFrom method.
    /// @param token Address of token to transfer.
    /// @param from Address to transfer token from.
    /// @param to Address to transfer token to.
    /// @param value Amount of token to transfer.
    function transferToken(
        address token,
        address from,
        address to,
        uint    value)
        onlyAuthorized
        external
    {
        if (value > 0 && from != to) {
            require(
                ERC20(token).transferFrom(from, to, value)
            );
        }
    }
    function batchTransferToken(
        uint ringSize, 
        address lrcTokenAddress,
        address feeRecipient,
        bytes32[] batch)
        onlyAuthorized
        external
    {
        require(batch.length == ringSize * 6);
        uint p = ringSize * 2;
        var lrc = ERC20(lrcTokenAddress);
        for (uint i = 0; i < ringSize; i++) {
            uint prev = ((i + ringSize - 1) % ringSize);
            address tokenS = address(batch[i]);
            address owner = address(batch[ringSize + i]);
            address prevOwner = address(batch[ringSize + prev]);
            
            // Pay tokenS to previous order, or to miner as previous order's
            // margin split or/and this order's margin split.
            ERC20 _tokenS;
            // Try to create ERC20 instances only once per token.
            if (owner != prevOwner || owner != feeRecipient && batch[p+1] != 0) {
                _tokenS = ERC20(tokenS);
            }
            // Here batch[p] has been checked not to be 0.
            if (owner != prevOwner) {
                require(
                    _tokenS.transferFrom(owner, prevOwner, uint(batch[p]))
                );
            }
            if (owner != feeRecipient) {
                if (batch[p+1] != 0) {
                    require(
                        _tokenS.transferFrom(owner, feeRecipient, uint(batch[p+1]))
                    );
                } 
                if (batch[p+2] != 0) {
                    require(
                        lrc.transferFrom(feeRecipient, owner, uint(batch[p+2]))
                    );
                }
                if (batch[p+3] != 0) {
                    require(
                        lrc.transferFrom(owner, feeRecipient, uint(batch[p+3]))
                    );
                }
            }
            p += 4;
        }
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"latestAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"max","type":"uint256"}],"name":"getLatestAuthorizedAddresses","outputs":[{"name":"addresses","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"ringSize","type":"uint256"},{"name":"lrcTokenAddress","type":"address"},{"name":"feeRecipient","type":"address"},{"name":"batch","type":"bytes32[]"}],"name":"batchTransferToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"authorizeAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"isAddressAuthorized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"deauthorizeAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"addr","type":"address"},{"indexed":false,"name":"number","type":"uint32"}],"name":"AddressAuthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"addr","type":"address"},{"indexed":false,"name":"number","type":"uint32"}],"name":"AddressDeauthorized","type":"event"}]

606060405260008054600160a060020a033316600160a060020a0319909116179055610c08806100306000396000f30060606040526004361061007f5763ffffffff60e060020a6000350416630d0567ae81146100845780632097dd04146100b35780632c54de4f1461011c57806335a506631461014c5780634a5db3b5146101835780638da5cb5b146101a2578063ced3fb9c146101b5578063f2fde38b146101e8578063f73857cc14610207575b600080fd5b341561008f57600080fd5b610097610226565b604051600160a060020a03909116815260200160405180910390f35b34156100be57600080fd5b6100c9600435610235565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156101085780820151838201526020016100f0565b505050509050019250505060405180910390f35b341561012757600080fd5b61014a600160a060020a0360043581169060243581169060443516606435610346565b005b341561015757600080fd5b61014a6004803590600160a060020a036024803582169260443590921691606435918201910135610417565b341561018e57600080fd5b61014a600160a060020a036004351661084f565b34156101ad57600080fd5b610097610a70565b34156101c057600080fd5b6101d4600160a060020a0360043516610a7f565b604051901515815260200160405180910390f35b34156101f357600080fd5b61014a600160a060020a0360043516610aa4565b341561021257600080fd5b61014a600160a060020a0360043516610afa565b600254600160a060020a031681565b61023d610baa565b6000610247610bbc565b6000846040518059106102575750595b9080825280602002602001820160405250600254909450600160a060020a03169250600090505b600160a060020a0383161580159061029557508085105b1561033e57600160a060020a03831660009081526001602052604090819020906060905190810160409081529154600160a060020a038116825260a060020a810463ffffffff166020830190815260c060020a90910460ff1615159282019290925292505163ffffffff16151561030b5761033e565b8284828060010193508151811061031e57fe5b600160a060020a039092166020928302909101909101528151925061027e565b505050919050565b61034f33610a7f565b151561035a57600080fd5b60008111801561037c575081600160a060020a031683600160a060020a031614155b156104115783600160a060020a03166323b872dd84848460006040516020015260405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b15156103eb57600080fd5b6102c65a03f115156103fc57600080fd5b50505060405180519050151561041157600080fd5b50505050565b60008060008060008060008061042c33610a7f565b151561043757600080fd5b60068d02891461044657600080fd5b8c60020297508b9650600095505b8c861015610840578c60018e88010381151561046c57fe5b06945089898781811061047b57fe5b602002919091013594508a9050898e880181811061049557fe5b602002919091013593508a9050898e87018181106104af57fe5b6020029190910135925050600160a060020a0383811690831614158061050957508a600160a060020a031683600160a060020a0316141580156105095750898960018a018181106104fc57fe5b6020029190910135151590505b156105115750825b600160a060020a03838116908316146105c957600160a060020a0381166323b872dd84848d8d8d81811061054157fe5b6020029190910135905060006040516020015260405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b15156105a357600080fd5b6102c65a03f115156105b457600080fd5b5050506040518051905015156105c957600080fd5b600160a060020a03838116908c161461082e57898960018a018181106105eb57fe5b60200291909101351590506106a257600160a060020a0381166323b872dd848d8d8d60018e0181811061061a57fe5b6020029190910135905060006040516020015260405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561067c57600080fd5b6102c65a03f1151561068d57600080fd5b5050506040518051905015156106a257600080fd5b898960028a018181106106b157fe5b602002919091013515905061076857600160a060020a0387166323b872dd8c858d8d60028e018181106106e057fe5b6020029190910135905060006040516020015260405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561074257600080fd5b6102c65a03f1151561075357600080fd5b50505060405180519050151561076857600080fd5b898960038a0181811061077757fe5b602002919091013515905061082e57600160a060020a0387166323b872dd848d8d8d60038e018181106107a657fe5b6020029190910135905060006040516020015260405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b151561080857600080fd5b6102c65a03f1151561081957600080fd5b50505060405180519050151561082e57600080fd5b60049790970196600190950194610454565b50505050505050505050505050565b60008054819033600160a060020a0390811691161461086d57600080fd5b600160a060020a0383166000908152600160205260409020805490925060a060020a900463ffffffff161561091c57815460c060020a900460ff16151561091757815460c060020a60ff02191660c060020a17808355600160a060020a038416907f3b61204456cbbcb12a2d6b3006f6a24187ac7d5eeef361a93bad25888eebbb309063ffffffff60a060020a9091041660405163ffffffff909116815260200160405180910390a25b610a6b565b50600254600160a060020a031680151561096c57815460c060020a60ff021977ffffffff00000000000000000000000000000000000000001990911660a060020a171660c060020a1782556109e0565b815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03821690811780845560009182526001602081905260409092205477ffffffff00000000000000000000000000000000000000001990911660a060020a9182900463ffffffff908116909301909216021782555b815460c060020a60ff02191660c060020a17825560028054600160a060020a03851673ffffffffffffffffffffffffffffffffffffffff19909116811790915582547f3b61204456cbbcb12a2d6b3006f6a24187ac7d5eeef361a93bad25888eebbb309063ffffffff60a060020a9091041660405163ffffffff909116815260200160405180910390a25b505050565b600054600160a060020a031681565b600160a060020a031660009081526001602052604090205460c060020a900460ff1690565b60005433600160a060020a03908116911614610abf57600080fd5b600160a060020a03811615610af7576000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b50565b6000805433600160a060020a03908116911614610b1657600080fd5b50600160a060020a03811660009081526001602052604090205460a060020a900463ffffffff168015610ba657600160a060020a03821660008181526001602052604090819020805460c060020a60ff02191690557fa407c1ccf2240ac410f40f8008c27443bf0d10c03f6fb4565e5796d3bf86a5be9083905163ffffffff909116815260200160405180910390a25b5050565b60206040519081016040526000815290565b6060604051908101604090815260008083526020830181905290820152905600a165627a7a72305820fa49dd2b6534baa62cdeed9598ca75f8225ccdcd1938f21f8dd223bfdfb4ec930029

Swarm Source

bzzr://fa49dd2b6534baa62cdeed9598ca75f8225ccdcd1938f21f8dd223bfdfb4ec93
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.