ETH Price: $1,599.65 (+1.16%)

Transaction Decoder

Block:
10478648 at Jul-17-2020 06:42:00 PM +UTC
Transaction Fee:
0.007020216000125361 ETH $11.23
Gas Used:
125,361 Gas / 56.000000001 Gwei

Emitted Events:

109 MultiSigWalletWithDailyLimit.Confirmation( sender=[Sender] 0x1f4f5967df6b5b70a2d7f1d031e12e7f4fc6e56c, transactionId=51 )
110 TokenOWLProxy.Transfer( from=[Receiver] MultiSigWalletWithDailyLimit, to=0x6d7f519a18e903b1642FdEB6419907B2b912CFbc, value=50050000000000000000000 )
111 MultiSigWalletWithDailyLimit.Execution( transactionId=51 )

Account State Difference:

  Address   Before After State Difference Code
(zhizhu.top)
3,953.234677798063809879 Eth3,953.24169801406393524 Eth0.007020216000125361
0x1A5F9352...6370d82e4
0x1F4f5967...f4fC6E56c
1.311195877300771689 Eth
Nonce: 58
1.304175661300646328 Eth
Nonce: 59
0.007020216000125361
0x31CbA7aD...5736a9615

Execution Trace

MultiSigWalletWithDailyLimit.confirmTransaction( transactionId=51 )
  • TokenOWLProxy.transfer( to=0x6d7f519a18e903b1642FdEB6419907B2b912CFbc, value=50050000000000000000000 ) => ( True )
    File 1 of 2: MultiSigWalletWithDailyLimit
    pragma solidity 0.4.4;
    
    
    /// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.
    /// @author Stefan George - <[email protected]>
    contract MultiSigWallet {
    
        uint constant public MAX_OWNER_COUNT = 50;
    
        event Confirmation(address indexed sender, uint indexed transactionId);
        event Revocation(address indexed sender, uint indexed transactionId);
        event Submission(uint indexed transactionId);
        event Execution(uint indexed transactionId);
        event ExecutionFailure(uint indexed transactionId);
        event Deposit(address indexed sender, uint value);
        event OwnerAddition(address indexed owner);
        event OwnerRemoval(address indexed owner);
        event RequirementChange(uint required);
    
        mapping (uint => Transaction) public transactions;
        mapping (uint => mapping (address => bool)) public confirmations;
        mapping (address => bool) public isOwner;
        address[] public owners;
        uint public required;
        uint public transactionCount;
    
        struct Transaction {
            address destination;
            uint value;
            bytes data;
            bool executed;
        }
    
        modifier onlyWallet() {
            if (msg.sender != address(this))
                throw;
            _;
        }
    
        modifier ownerDoesNotExist(address owner) {
            if (isOwner[owner])
                throw;
            _;
        }
    
        modifier ownerExists(address owner) {
            if (!isOwner[owner])
                throw;
            _;
        }
    
        modifier transactionExists(uint transactionId) {
            if (transactions[transactionId].destination == 0)
                throw;
            _;
        }
    
        modifier confirmed(uint transactionId, address owner) {
            if (!confirmations[transactionId][owner])
                throw;
            _;
        }
    
        modifier notConfirmed(uint transactionId, address owner) {
            if (confirmations[transactionId][owner])
                throw;
            _;
        }
    
        modifier notExecuted(uint transactionId) {
            if (transactions[transactionId].executed)
                throw;
            _;
        }
    
        modifier notNull(address _address) {
            if (_address == 0)
                throw;
            _;
        }
    
        modifier validRequirement(uint ownerCount, uint _required) {
            if (   ownerCount > MAX_OWNER_COUNT
                || _required > ownerCount
                || _required == 0
                || ownerCount == 0)
                throw;
            _;
        }
    
        /// @dev Fallback function allows to deposit ether.
        function()
            payable
        {
            if (msg.value > 0)
                Deposit(msg.sender, msg.value);
        }
    
        /*
         * Public functions
         */
        /// @dev Contract constructor sets initial owners and required number of confirmations.
        /// @param _owners List of initial owners.
        /// @param _required Number of required confirmations.
        function MultiSigWallet(address[] _owners, uint _required)
            public
            validRequirement(_owners.length, _required)
        {
            for (uint i=0; i<_owners.length; i++) {
                if (isOwner[_owners[i]] || _owners[i] == 0)
                    throw;
                isOwner[_owners[i]] = true;
            }
            owners = _owners;
            required = _required;
        }
    
        /// @dev Allows to add a new owner. Transaction has to be sent by wallet.
        /// @param owner Address of new owner.
        function addOwner(address owner)
            public
            onlyWallet
            ownerDoesNotExist(owner)
            notNull(owner)
            validRequirement(owners.length + 1, required)
        {
            isOwner[owner] = true;
            owners.push(owner);
            OwnerAddition(owner);
        }
    
        /// @dev Allows to remove an owner. Transaction has to be sent by wallet.
        /// @param owner Address of owner.
        function removeOwner(address owner)
            public
            onlyWallet
            ownerExists(owner)
        {
            isOwner[owner] = false;
            for (uint i=0; i<owners.length - 1; i++)
                if (owners[i] == owner) {
                    owners[i] = owners[owners.length - 1];
                    break;
                }
            owners.length -= 1;
            if (required > owners.length)
                changeRequirement(owners.length);
            OwnerRemoval(owner);
        }
    
        /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.
        /// @param owner Address of owner to be replaced.
        /// @param owner Address of new owner.
        function replaceOwner(address owner, address newOwner)
            public
            onlyWallet
            ownerExists(owner)
            ownerDoesNotExist(newOwner)
        {
            for (uint i=0; i<owners.length; i++)
                if (owners[i] == owner) {
                    owners[i] = newOwner;
                    break;
                }
            isOwner[owner] = false;
            isOwner[newOwner] = true;
            OwnerRemoval(owner);
            OwnerAddition(newOwner);
        }
    
        /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.
        /// @param _required Number of required confirmations.
        function changeRequirement(uint _required)
            public
            onlyWallet
            validRequirement(owners.length, _required)
        {
            required = _required;
            RequirementChange(_required);
        }
    
        /// @dev Allows an owner to submit and confirm a transaction.
        /// @param destination Transaction target address.
        /// @param value Transaction ether value.
        /// @param data Transaction data payload.
        /// @return Returns transaction ID.
        function submitTransaction(address destination, uint value, bytes data)
            public
            returns (uint transactionId)
        {
            transactionId = addTransaction(destination, value, data);
            confirmTransaction(transactionId);
        }
    
        /// @dev Allows an owner to confirm a transaction.
        /// @param transactionId Transaction ID.
        function confirmTransaction(uint transactionId)
            public
            ownerExists(msg.sender)
            transactionExists(transactionId)
            notConfirmed(transactionId, msg.sender)
        {
            confirmations[transactionId][msg.sender] = true;
            Confirmation(msg.sender, transactionId);
            executeTransaction(transactionId);
        }
    
        /// @dev Allows an owner to revoke a confirmation for a transaction.
        /// @param transactionId Transaction ID.
        function revokeConfirmation(uint transactionId)
            public
            ownerExists(msg.sender)
            confirmed(transactionId, msg.sender)
            notExecuted(transactionId)
        {
            confirmations[transactionId][msg.sender] = false;
            Revocation(msg.sender, transactionId);
        }
    
        /// @dev Allows anyone to execute a confirmed transaction.
        /// @param transactionId Transaction ID.
        function executeTransaction(uint transactionId)
            public
            notExecuted(transactionId)
        {
            if (isConfirmed(transactionId)) {
                Transaction tx = transactions[transactionId];
                tx.executed = true;
                if (tx.destination.call.value(tx.value)(tx.data))
                    Execution(transactionId);
                else {
                    ExecutionFailure(transactionId);
                    tx.executed = false;
                }
            }
        }
    
        /// @dev Returns the confirmation status of a transaction.
        /// @param transactionId Transaction ID.
        /// @return Confirmation status.
        function isConfirmed(uint transactionId)
            public
            constant
            returns (bool)
        {
            uint count = 0;
            for (uint i=0; i<owners.length; i++) {
                if (confirmations[transactionId][owners[i]])
                    count += 1;
                if (count == required)
                    return true;
            }
        }
    
        /*
         * Internal functions
         */
        /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.
        /// @param destination Transaction target address.
        /// @param value Transaction ether value.
        /// @param data Transaction data payload.
        /// @return Returns transaction ID.
        function addTransaction(address destination, uint value, bytes data)
            internal
            notNull(destination)
            returns (uint transactionId)
        {
            transactionId = transactionCount;
            transactions[transactionId] = Transaction({
                destination: destination,
                value: value,
                data: data,
                executed: false
            });
            transactionCount += 1;
            Submission(transactionId);
        }
    
        /*
         * Web3 call functions
         */
        /// @dev Returns number of confirmations of a transaction.
        /// @param transactionId Transaction ID.
        /// @return Number of confirmations.
        function getConfirmationCount(uint transactionId)
            public
            constant
            returns (uint count)
        {
            for (uint i=0; i<owners.length; i++)
                if (confirmations[transactionId][owners[i]])
                    count += 1;
        }
    
        /// @dev Returns total number of transactions after filers are applied.
        /// @param pending Include pending transactions.
        /// @param executed Include executed transactions.
        /// @return Total number of transactions after filters are applied.
        function getTransactionCount(bool pending, bool executed)
            public
            constant
            returns (uint count)
        {
            for (uint i=0; i<transactionCount; i++)
                if (   pending && !transactions[i].executed
                    || executed && transactions[i].executed)
                    count += 1;
        }
    
        /// @dev Returns list of owners.
        /// @return List of owner addresses.
        function getOwners()
            public
            constant
            returns (address[])
        {
            return owners;
        }
    
        /// @dev Returns array with owner addresses, which confirmed transaction.
        /// @param transactionId Transaction ID.
        /// @return Returns array of owner addresses.
        function getConfirmations(uint transactionId)
            public
            constant
            returns (address[] _confirmations)
        {
            address[] memory confirmationsTemp = new address[](owners.length);
            uint count = 0;
            uint i;
            for (i=0; i<owners.length; i++)
                if (confirmations[transactionId][owners[i]]) {
                    confirmationsTemp[count] = owners[i];
                    count += 1;
                }
            _confirmations = new address[](count);
            for (i=0; i<count; i++)
                _confirmations[i] = confirmationsTemp[i];
        }
    
        /// @dev Returns list of transaction IDs in defined range.
        /// @param from Index start position of transaction array.
        /// @param to Index end position of transaction array.
        /// @param pending Include pending transactions.
        /// @param executed Include executed transactions.
        /// @return Returns array of transaction IDs.
        function getTransactionIds(uint from, uint to, bool pending, bool executed)
            public
            constant
            returns (uint[] _transactionIds)
        {
            uint[] memory transactionIdsTemp = new uint[](transactionCount);
            uint count = 0;
            uint i;
            for (i=0; i<transactionCount; i++)
                if (   pending && !transactions[i].executed
                    || executed && transactions[i].executed)
                {
                    transactionIdsTemp[count] = i;
                    count += 1;
                }
            _transactionIds = new uint[](to - from);
            for (i=from; i<to; i++)
                _transactionIds[i - from] = transactionIdsTemp[i];
        }
    }
    
    /// @title Multisignature wallet with daily limit - Allows an owner to withdraw a daily limit without multisig.
    /// @author Stefan George - <[email protected]>
    contract MultiSigWalletWithDailyLimit is MultiSigWallet {
    
        event DailyLimitChange(uint dailyLimit);
    
        uint public dailyLimit;
        uint public lastDay;
        uint public spentToday;
    
        /*
         * Public functions
         */
        /// @dev Contract constructor sets initial owners, required number of confirmations and daily withdraw limit.
        /// @param _owners List of initial owners.
        /// @param _required Number of required confirmations.
        /// @param _dailyLimit Amount in wei, which can be withdrawn without confirmations on a daily basis.
        function MultiSigWalletWithDailyLimit(address[] _owners, uint _required, uint _dailyLimit)
            public
            MultiSigWallet(_owners, _required)
        {
            dailyLimit = _dailyLimit;
        }
    
        /// @dev Allows to change the daily limit. Transaction has to be sent by wallet.
        /// @param _dailyLimit Amount in wei.
        function changeDailyLimit(uint _dailyLimit)
            public
            onlyWallet
        {
            dailyLimit = _dailyLimit;
            DailyLimitChange(_dailyLimit);
        }
    
        /// @dev Allows anyone to execute a confirmed transaction or ether withdraws until daily limit is reached.
        /// @param transactionId Transaction ID.
        function executeTransaction(uint transactionId)
            public
            notExecuted(transactionId)
        {
            Transaction tx = transactions[transactionId];
            bool confirmed = isConfirmed(transactionId);
            if (confirmed || tx.data.length == 0 && isUnderLimit(tx.value)) {
                tx.executed = true;
                if (!confirmed)
                    spentToday += tx.value;
                if (tx.destination.call.value(tx.value)(tx.data))
                    Execution(transactionId);
                else {
                    ExecutionFailure(transactionId);
                    tx.executed = false;
                    if (!confirmed)
                        spentToday -= tx.value;
                }
            }
        }
    
        /*
         * Internal functions
         */
        /// @dev Returns if amount is within daily limit and resets spentToday after one day.
        /// @param amount Amount to withdraw.
        /// @return Returns if amount is under daily limit.
        function isUnderLimit(uint amount)
            internal
            returns (bool)
        {
            if (now > lastDay + 24 hours) {
                lastDay = now;
                spentToday = 0;
            }
            if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)
                return false;
            return true;
        }
    
        /*
         * Web3 call functions
         */
        /// @dev Returns maximum withdraw amount.
        /// @return Returns amount.
        function calcMaxWithdraw()
            public
            constant
            returns (uint)
        {
            if (now > lastDay + 24 hours)
                return dailyLimit;
            return dailyLimit - spentToday;
        }
    }

    File 2 of 2: TokenOWLProxy
    pragma solidity ^0.4.21;
    
    // File: @gnosis.pm/util-contracts/contracts/Proxy.sol
    
    /// @title Proxied - indicates that a contract will be proxied. Also defines storage requirements for Proxy.
    /// @author Alan Lu - <[email protected]>
    contract Proxied {
        address public masterCopy;
    }
    
    /// @title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.
    /// @author Stefan George - <[email protected]>
    contract Proxy is Proxied {
        /// @dev Constructor function sets address of master copy contract.
        /// @param _masterCopy Master copy address.
        function Proxy(address _masterCopy)
            public
        {
            require(_masterCopy != 0);
            masterCopy = _masterCopy;
        }
    
        /// @dev Fallback function forwards all transactions and returns all received return data.
        function ()
            external
            payable
        {
            address _masterCopy = masterCopy;
            assembly {
                calldatacopy(0, 0, calldatasize())
                let success := delegatecall(not(0), _masterCopy, 0, calldatasize(), 0, 0)
                returndatacopy(0, 0, returndatasize())
                switch success
                case 0 { revert(0, returndatasize()) }
                default { return(0, returndatasize()) }
            }
        }
    }
    
    // File: @gnosis.pm/util-contracts/contracts/Math.sol
    
    /// @title Math library - Allows calculation of logarithmic and exponential functions
    /// @author Alan Lu - <[email protected]>
    /// @author Stefan George - <[email protected]>
    library Math {
    
        /*
         *  Constants
         */
        // This is equal to 1 in our calculations
        uint public constant ONE =  0x10000000000000000;
        uint public constant LN2 = 0xb17217f7d1cf79ac;
        uint public constant LOG2_E = 0x171547652b82fe177;
    
        /*
         *  Public functions
         */
        /// @dev Returns natural exponential function value of given x
        /// @param x x
        /// @return e**x
        function exp(int x)
            public
            pure
            returns (uint)
        {
            // revert if x is > MAX_POWER, where
            // MAX_POWER = int(mp.floor(mp.log(mpf(2**256 - 1) / ONE) * ONE))
            require(x <= 2454971259878909886679);
            // return 0 if exp(x) is tiny, using
            // MIN_POWER = int(mp.floor(mp.log(mpf(1) / ONE) * ONE))
            if (x < -818323753292969962227)
                return 0;
            // Transform so that e^x -> 2^x
            x = x * int(ONE) / int(LN2);
            // 2^x = 2^whole(x) * 2^frac(x)
            //       ^^^^^^^^^^ is a bit shift
            // so Taylor expand on z = frac(x)
            int shift;
            uint z;
            if (x >= 0) {
                shift = x / int(ONE);
                z = uint(x % int(ONE));
            }
            else {
                shift = x / int(ONE) - 1;
                z = ONE - uint(-x % int(ONE));
            }
            // 2^x = 1 + (ln 2) x + (ln 2)^2/2! x^2 + ...
            //
            // Can generate the z coefficients using mpmath and the following lines
            // >>> from mpmath import mp
            // >>> mp.dps = 100
            // >>> ONE =  0x10000000000000000
            // >>> print('\n'.join(hex(int(mp.log(2)**i / mp.factorial(i) * ONE)) for i in range(1, 7)))
            // 0xb17217f7d1cf79ab
            // 0x3d7f7bff058b1d50
            // 0xe35846b82505fc5
            // 0x276556df749cee5
            // 0x5761ff9e299cc4
            // 0xa184897c363c3
            uint zpow = z;
            uint result = ONE;
            result += 0xb17217f7d1cf79ab * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x3d7f7bff058b1d50 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0xe35846b82505fc5 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x276556df749cee5 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x5761ff9e299cc4 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0xa184897c363c3 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0xffe5fe2c4586 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x162c0223a5c8 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x1b5253d395e * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x1e4cf5158b * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x1e8cac735 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x1c3bd650 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x1816193 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x131496 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0xe1b7 * zpow / ONE;
            zpow = zpow * z / ONE;
            result += 0x9c7 * zpow / ONE;
            if (shift >= 0) {
                if (result >> (256-shift) > 0)
                    return (2**256-1);
                return result << shift;
            }
            else
                return result >> (-shift);
        }
    
        /// @dev Returns natural logarithm value of given x
        /// @param x x
        /// @return ln(x)
        function ln(uint x)
            public
            pure
            returns (int)
        {
            require(x > 0);
            // binary search for floor(log2(x))
            int ilog2 = floorLog2(x);
            int z;
            if (ilog2 < 0)
                z = int(x << uint(-ilog2));
            else
                z = int(x >> uint(ilog2));
            // z = x * 2^-⌊log₂x⌋
            // so 1 <= z < 2
            // and ln z = ln x - ⌊log₂x⌋/log₂e
            // so just compute ln z using artanh series
            // and calculate ln x from that
            int term = (z - int(ONE)) * int(ONE) / (z + int(ONE));
            int halflnz = term;
            int termpow = term * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 3;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 5;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 7;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 9;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 11;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 13;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 15;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 17;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 19;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 21;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 23;
            termpow = termpow * term / int(ONE) * term / int(ONE);
            halflnz += termpow / 25;
            return (ilog2 * int(ONE)) * int(ONE) / int(LOG2_E) + 2 * halflnz;
        }
    
        /// @dev Returns base 2 logarithm value of given x
        /// @param x x
        /// @return logarithmic value
        function floorLog2(uint x)
            public
            pure
            returns (int lo)
        {
            lo = -64;
            int hi = 193;
            // I use a shift here instead of / 2 because it floors instead of rounding towards 0
            int mid = (hi + lo) >> 1;
            while((lo + 1) < hi) {
                if (mid < 0 && x << uint(-mid) < ONE || mid >= 0 && x >> uint(mid) < ONE)
                    hi = mid;
                else
                    lo = mid;
                mid = (hi + lo) >> 1;
            }
        }
    
        /// @dev Returns maximum of an array
        /// @param nums Numbers to look through
        /// @return Maximum number
        function max(int[] nums)
            public
            pure
            returns (int maxNum)
        {
            require(nums.length > 0);
            maxNum = -2**255;
            for (uint i = 0; i < nums.length; i++)
                if (nums[i] > maxNum)
                    maxNum = nums[i];
        }
    
        /// @dev Returns whether an add operation causes an overflow
        /// @param a First addend
        /// @param b Second addend
        /// @return Did no overflow occur?
        function safeToAdd(uint a, uint b)
            internal
            pure
            returns (bool)
        {
            return a + b >= a;
        }
    
        /// @dev Returns whether a subtraction operation causes an underflow
        /// @param a Minuend
        /// @param b Subtrahend
        /// @return Did no underflow occur?
        function safeToSub(uint a, uint b)
            internal
            pure
            returns (bool)
        {
            return a >= b;
        }
    
        /// @dev Returns whether a multiply operation causes an overflow
        /// @param a First factor
        /// @param b Second factor
        /// @return Did no overflow occur?
        function safeToMul(uint a, uint b)
            internal
            pure
            returns (bool)
        {
            return b == 0 || a * b / b == a;
        }
    
        /// @dev Returns sum if no overflow occurred
        /// @param a First addend
        /// @param b Second addend
        /// @return Sum
        function add(uint a, uint b)
            internal
            pure
            returns (uint)
        {
            require(safeToAdd(a, b));
            return a + b;
        }
    
        /// @dev Returns difference if no overflow occurred
        /// @param a Minuend
        /// @param b Subtrahend
        /// @return Difference
        function sub(uint a, uint b)
            internal
            pure
            returns (uint)
        {
            require(safeToSub(a, b));
            return a - b;
        }
    
        /// @dev Returns product if no overflow occurred
        /// @param a First factor
        /// @param b Second factor
        /// @return Product
        function mul(uint a, uint b)
            internal
            pure
            returns (uint)
        {
            require(safeToMul(a, b));
            return a * b;
        }
    
        /// @dev Returns whether an add operation causes an overflow
        /// @param a First addend
        /// @param b Second addend
        /// @return Did no overflow occur?
        function safeToAdd(int a, int b)
            internal
            pure
            returns (bool)
        {
            return (b >= 0 && a + b >= a) || (b < 0 && a + b < a);
        }
    
        /// @dev Returns whether a subtraction operation causes an underflow
        /// @param a Minuend
        /// @param b Subtrahend
        /// @return Did no underflow occur?
        function safeToSub(int a, int b)
            internal
            pure
            returns (bool)
        {
            return (b >= 0 && a - b <= a) || (b < 0 && a - b > a);
        }
    
        /// @dev Returns whether a multiply operation causes an overflow
        /// @param a First factor
        /// @param b Second factor
        /// @return Did no overflow occur?
        function safeToMul(int a, int b)
            internal
            pure
            returns (bool)
        {
            return (b == 0) || (a * b / b == a);
        }
    
        /// @dev Returns sum if no overflow occurred
        /// @param a First addend
        /// @param b Second addend
        /// @return Sum
        function add(int a, int b)
            internal
            pure
            returns (int)
        {
            require(safeToAdd(a, b));
            return a + b;
        }
    
        /// @dev Returns difference if no overflow occurred
        /// @param a Minuend
        /// @param b Subtrahend
        /// @return Difference
        function sub(int a, int b)
            internal
            pure
            returns (int)
        {
            require(safeToSub(a, b));
            return a - b;
        }
    
        /// @dev Returns product if no overflow occurred
        /// @param a First factor
        /// @param b Second factor
        /// @return Product
        function mul(int a, int b)
            internal
            pure
            returns (int)
        {
            require(safeToMul(a, b));
            return a * b;
        }
    }
    
    // File: @gnosis.pm/util-contracts/contracts/Token.sol
    
    /// Implements ERC 20 Token standard: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
    pragma solidity ^0.4.21;
    
    
    /// @title Abstract token contract - Functions to be implemented by token contracts
    contract Token {
    
        /*
         *  Events
         */
        event Transfer(address indexed from, address indexed to, uint value);
        event Approval(address indexed owner, address indexed spender, uint value);
    
        /*
         *  Public functions
         */
        function transfer(address to, uint value) public returns (bool);
        function transferFrom(address from, address to, uint value) public returns (bool);
        function approve(address spender, uint value) public returns (bool);
        function balanceOf(address owner) public view returns (uint);
        function allowance(address owner, address spender) public view returns (uint);
        function totalSupply() public view returns (uint);
    }
    
    // File: @gnosis.pm/util-contracts/contracts/StandardToken.sol
    
    contract StandardTokenData {
    
        /*
         *  Storage
         */
        mapping (address => uint) balances;
        mapping (address => mapping (address => uint)) allowances;
        uint totalTokens;
    }
    
    /// @title Standard token contract with overflow protection
    contract StandardToken is Token, StandardTokenData {
        using Math for *;
    
        /*
         *  Public functions
         */
        /// @dev Transfers sender's tokens to a given address. Returns success
        /// @param to Address of token receiver
        /// @param value Number of tokens to transfer
        /// @return Was transfer successful?
        function transfer(address to, uint value)
            public
            returns (bool)
        {
            if (   !balances[msg.sender].safeToSub(value)
                || !balances[to].safeToAdd(value))
                return false;
            balances[msg.sender] -= value;
            balances[to] += value;
            emit Transfer(msg.sender, to, value);
            return true;
        }
    
        /// @dev Allows allowed third party to transfer tokens from one address to another. Returns success
        /// @param from Address from where tokens are withdrawn
        /// @param to Address to where tokens are sent
        /// @param value Number of tokens to transfer
        /// @return Was transfer successful?
        function transferFrom(address from, address to, uint value)
            public
            returns (bool)
        {
            if (   !balances[from].safeToSub(value)
                || !allowances[from][msg.sender].safeToSub(value)
                || !balances[to].safeToAdd(value))
                return false;
            balances[from] -= value;
            allowances[from][msg.sender] -= value;
            balances[to] += value;
            emit Transfer(from, to, value);
            return true;
        }
    
        /// @dev Sets approved amount of tokens for spender. Returns success
        /// @param spender Address of allowed account
        /// @param value Number of approved tokens
        /// @return Was approval successful?
        function approve(address spender, uint value)
            public
            returns (bool)
        {
            allowances[msg.sender][spender] = value;
            emit Approval(msg.sender, spender, value);
            return true;
        }
    
        /// @dev Returns number of allowed tokens for given address
        /// @param owner Address of token owner
        /// @param spender Address of token spender
        /// @return Remaining allowance for spender
        function allowance(address owner, address spender)
            public
            view
            returns (uint)
        {
            return allowances[owner][spender];
        }
    
        /// @dev Returns number of tokens owned by given address
        /// @param owner Address of token owner
        /// @return Balance of owner
        function balanceOf(address owner)
            public
            view
            returns (uint)
        {
            return balances[owner];
        }
    
        /// @dev Returns total supply of tokens
        /// @return Total supply
        function totalSupply()
            public
            view
            returns (uint)
        {
            return totalTokens;
        }
    }
    
    // File: contracts/TokenOWLProxy.sol
    
    contract TokenOWLProxy is Proxy, StandardToken {
        using Math for *;
    
        string public constant name = "OWL Token";
        string public constant symbol = "OWL";
        uint8 public constant decimals = 18;
    
        struct masterCopyCountdownType {
            address masterCopy;
            uint timeWhenAvailable;
        }
    
        masterCopyCountdownType masterCopyCountdown;
    
        address public creator;
        address public minter;
    
        /// @dev Constructor of the contract OWL, which distributes tokens
        function TokenOWLProxy(address proxied)
            Proxy(proxied)
            public
        {
            creator = msg.sender;
        }
    }