ETH Price: $3,238.27 (-0.48%)

Contract

0x20941C5cf19d5C347b9EdF26f6C9b0a70be996A1
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Call Tx82144292019-07-24 16:27:391997 days ago1563985659IN
0x20941C5c...70be996A1
0 ETH0.0029405524

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x412Fc2E8...5A295D027
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
NiftyWallet

Compiler Version
v0.5.4+commit.9549d8ff

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
/**
 *Submitted for verification at Etherscan.io on 2019-05-06
*/

pragma solidity ^0.5.4;

contract NiftyWallet {
    
    /**
     * The Nifty Wallet - the niftiest wallet around!
     * Author - Duncan Cock Foster. [email protected] 
     */ 

    /**
     * Constants 
     * The address of the master contract, and the account ID for this wallet
     * Account ID is used to retrieve the signing private key for this wallet
     */ 

    address masterContractAdd = 0x4CADB4bAd0e2a49CC5D6CE26D8628C8f451dA346;
    uint userAccountID = 0;
    uint walletTxCount = 0;

    /**
    / Events
    */

    event Execution(address indexed destinationAddress, uint value, bytes txData);
    event ExecutionFailure(address indexed destinationAddress, uint value, bytes txData);
    event Deposit(address indexed sender, uint value);

    /**
    * @dev returns signing private key that controls this wallet
    */

    function returnUserAccountAddress() public view returns(address) {
        MasterContract m_c_instance = MasterContract(masterContractAdd);
        return (m_c_instance.returnUserControlAddress(userAccountID));
    }
    
    function returnWalletTxCount() public view returns(uint) {
        return(walletTxCount);
    }
    
    /**
     * Modifier to check msg.sender
     */
     
    modifier onlyValidSender() {
        MasterContract m_c_instance = MasterContract(masterContractAdd);
        require(m_c_instance.returnIsValidSendingKey(msg.sender) == true);
        _;
      }

    /** 
     * Fall back function - get paid and static calls
     */ 

    function()
        payable
        external
    {
        if (msg.value > 0)
            emit Deposit(msg.sender, msg.value);
        else if (msg.data.length > 0) {
            //static call 
            MasterContract m_c_instance = MasterContract(masterContractAdd);
            address loc =  (m_c_instance.returnStaticContractAddress());
                assembly {
                    calldatacopy(0, 0, calldatasize())
                    let result := staticcall(gas, loc, 0, calldatasize(), 0, 0)
                    returndatacopy(0, 0, returndatasize())
                    switch result 
                    case 0 {revert(0, returndatasize())} 
                    default {return (0, returndatasize())}
                }
        }
    }
    
    /**
     * @dev function to call any on chain transaction
     * @dev verifies that the transaction data has been signed by the wallets controlling private key
     * @dev and that the transaction has been sent from an approved sending wallet
     * @param  _signedData bytes - signature of txData + wallet address
     * @param destination address - destination for this transaction
     * @param value uint - value of this transaction
     * @param data bytes - transaction data 
     */ 

    function callTx(bytes memory _signedData,
                     address destination,
                     uint value,
                     bytes memory data)
    public onlyValidSender returns (bool) {
        address userSigningAddress = returnUserAccountAddress();
        MasterContract m_c_instance = MasterContract(masterContractAdd);
        bytes32 dataHash = m_c_instance.returnTxMessageToSign(data, destination, value, walletTxCount);
        address recoveredAddress = m_c_instance.recover(dataHash, _signedData);
        if (recoveredAddress==userSigningAddress) {
            if (external_call(destination, value, data.length, data)) {
                emit Execution(destination, value, data);
                walletTxCount = walletTxCount + 1;
            } else {
                emit ExecutionFailure(destination, value, data);
                walletTxCount = walletTxCount +1;
            }
            return(true);
        } else {
            revert();
        }
    }
    
    /** External call function 
     * Taken from Gnosis Mutli Sig wallet
     * https://github.com/gnosis/MultiSigWallet/blob/master/contracts/MultiSigWallet.sol
     */ 

    // call has been separated into its own function in order to take advantage
    // of the Solidity's code generator to produce a loop that copies tx.data into memory.
    function external_call(address destination, uint value, uint dataLength, bytes memory data) private returns (bool) {
        bool result;
        assembly {
            let x := mload(0x40)   // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention)
            let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that
            result := call(
                sub(gas, 34710),   // 34710 is the value that solidity is currently emitting
                                   // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +
                                   // callNewAccountGas (25000, in case the destination address does not exist and needs creating)
                destination,
                value,
                d,
                dataLength,        // Size of the input (in bytes) - this is what fixes the padding problem
                x,
                0                  // Output is ignored, therefore the output size is zero
            )
        }
        return result;
    }

}

contract MasterContract {
    function returnUserControlAddress(uint account_id) public view returns (address);
    function returnIsValidSendingKey(address sending_key) public view returns (bool);
    function returnStaticContractAddress() public view returns (address);
    function recover(bytes32 hash, bytes memory sig) public pure returns (address);
    function returnTxMessageToSign(bytes memory txData, address des_add, uint value, uint tx_count)
    public view returns(bytes32);
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"returnUserAccountAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"returnWalletTxCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_signedData","type":"bytes"},{"name":"destination","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"callTx","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"destinationAddress","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"txData","type":"bytes"}],"name":"Execution","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"destinationAddress","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"txData","type":"bytes"}],"name":"ExecutionFailure","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Deposit","type":"event"}]

Deployed Bytecode

0x608060405260043610610051576000357c01000000000000000000000000000000000000000000000000000000009004806361515334146101a95780636d9b501a146102005780636de725a31461022b575b60003411156100ad573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a26101a7565b60008036905011156101a65760008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1663b0bb7ebd6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561014357600080fd5b505afa158015610157573d6000803e3d6000fd5b505050506040513d602081101561016d57600080fd5b810190808051906020019092919050505090503660008037600080366000845afa3d6000803e80600081146101a1573d6000f35b3d6000fd5b5b005b3480156101b557600080fd5b506101be6103cc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561020c57600080fd5b506102156104a3565b6040518082815260200191505060405180910390f35b34801561023757600080fd5b506103b26004803603608081101561024e57600080fd5b810190808035906020019064010000000081111561026b57600080fd5b82018360208201111561027d57600080fd5b8035906020019184600183028401116401000000008311171561029f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561032c57600080fd5b82018360208201111561033e57600080fd5b8035906020019184600183028401116401000000008311171561036057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506104ad565b604051808215151515815260200191505060405180910390f35b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663ec9614a16001546040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082815260200191505060206040518083038186803b15801561046257600080fd5b505afa158015610476573d6000803e3d6000fd5b505050506040513d602081101561048c57600080fd5b810190808051906020019092919050505091505090565b6000600254905090565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600115158173ffffffffffffffffffffffffffffffffffffffff1663d9ea7ed5336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561057157600080fd5b505afa158015610585573d6000803e3d6000fd5b505050506040513d602081101561059b57600080fd5b810190808051906020019092919050505015151415156105ba57600080fd5b60006105c46103cc565b905060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1663a334f5c4878a8a6002546040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b838110156106b957808201518184015260208101905061069e565b50505050905090810190601f1680156106e65780820380516001836020036101000a031916815260200191505b509550505050505060206040518083038186803b15801561070657600080fd5b505afa15801561071a573d6000803e3d6000fd5b505050506040513d602081101561073057600080fd5b8101908080519060200190929190505050905060008273ffffffffffffffffffffffffffffffffffffffff166319045a25838c6040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156107d45780820151818401526020810190506107b9565b50505050905090810190601f1680156108015780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561081f57600080fd5b505afa158015610833573d6000803e3d6000fd5b505050506040513d602081101561084957600080fd5b810190808051906020019092919050505090508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a435761089d898989518a610a51565b1561096e578873ffffffffffffffffffffffffffffffffffffffff167f39f46e1dedea184144e3feaf4e595d78345d9a9d8b43da87912efbe4df3c8a3189896040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610922578082015181840152602081019050610907565b50505050905090810190601f16801561094f5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2600160025401600281905550610a36565b8873ffffffffffffffffffffffffffffffffffffffff167f8d1ecf04e6462600e647fec505da5fb931c5d7e2c8171df5f6629beab50ec07f89896040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156109ee5780820151818401526020810190506109d3565b50505050905090810190601f168015610a1b5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a26001600254016002819055505b6001955050505050610a48565b600080fd5b50949350505050565b6000806040516020840160008287838a8c6187965a03f1925050508091505094935050505056fea165627a7a7230582036e99defe539766cc429067119c27376282be6065540aea21fd30a058716b0110029

Swarm Source

bzzr://36e99defe539766cc429067119c27376282be6065540aea21fd30a058716b011

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.