Contract 0xf0511f123164602042ab2bcf02111fa5d3fe97cd 1

 

Contract Overview

Balance:
0 MATIC

MATIC Value:
$0.00

Token:
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x758e39340ea6522227928da7d9fe78803660b57ab369d03d564972abd32ef213Execute EIP712338586512022-10-03 0:58:241 min ago0x860ea4f47bf3917549cf558b0173ee0898480afe IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.006570812182 36.369943332
0x51d9152af87f50e79c94d85fc18a0aa8a3cc27c428013de32e257fd36e39c281Execute EIP712338586322022-10-03 0:57:462 mins ago0x0e7d563199e70852c185dc66ac1ca7d13d6b9b5f IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.007436863008 35.01496301
0x9a13291f425d345edd9659d85d88145e89a3a757024a3ed9cc46efc44c2cab79Execute EIP712338586102022-10-03 0:56:583 mins ago0xa6869c3001de171c26418e9e2eedca1c0d763ee2 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.006061008286 34.70990148
0x276bb5a2c0c44a2c5d4047cccb9a229e3cf1ddccebad921f931d8f45931cacacExecute EIP712338585992022-10-03 0:56:363 mins ago0x90e5fbf47b03c4192d3aa5de18acd5c1ad9d91cf IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.005908001578 35.873250986
0xd79887836888597d335aec57a99686d891f719dc062946d8f6c3684826b946adExecute EIP712338585932022-10-03 0:56:243 mins ago0x1069ec7c6d056d4e5715ffe3ab0e132cd02df3ad IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.00713594686 36.33448166
0x2dcf618d0b007b804571cb7f581678298ef64eddd77c8cc64c7da33a53072cadExecute EIP712338585482022-10-03 0:54:505 mins ago0xfeb2877e61fcc606025bcc7a72389642bee9d922 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.00668595122 37.007246635
0x07525f84006996becf6280ff0be929f64b9ce63ae5e216c0b6905b260e762aa6Execute EIP712338584802022-10-03 0:52:307 mins ago0x24e2d55d5ab48093ee196b7b65eb456dcdfca369 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.011694919026 64.732262998
0xed81d596ea41942d11eb4a73ecfe21bd603c0d6e26990e962c2ec28244d9ca9fExecute EIP712338584642022-10-03 0:51:588 mins ago0x708f2cd1c0b709d6f2138ddd9de1df0d807b953e IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.006094598189 37.013453196
0xe1ba6df68237771d4e9e495a7436d4469e4777b79670e313a0bcc6b34b064fbbExecute Personal...338584032022-10-03 0:49:5210 mins ago0x20d21f8794445df6412cab30076291cdf14fd0ee IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.003081320551 34.650000016
0xcac289d44db29fdf170895a2808668d02c5415145b7bb72fc59e5ce3ec4bcfadExecute EIP712338583432022-10-03 0:47:4812 mins ago0x1adbd686b0b750b042c0742e72a88e413d9be36d IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.00712049774 39.408132012
0xdd3ab7cd062ec68d42cb80eae0d609949a6ed337f9ea618f11bf4b738262370eExecute EIP712338583402022-10-03 0:47:4212 mins ago0x2a9841756b233a573cbe871893dba00618bc4aba IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.006861296309 37.980317679
0x9323c2e91a0cc7cf1cbd357560fb58ee6021e53fbdaec9053e0b3c02d6c73260Execute EIP712338583242022-10-03 0:47:1013 mins ago0x30a33432858db2728e622f86609c1a1edc0da750 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.006033401147 36.639123752
0x2aed0b55b9254cae3dce8caa737599d88b123ff4d04722ed9d62ecc910790b37Execute EIP712338583042022-10-03 0:46:3013 mins ago0x154a09b3a7375202ed970f81acf873156eeb74f8 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.00590492181 35.854550706
0x0c6c9e289a1c40e6ffc17644dbbf1d99f17dce1fb9aa87ed8651d29b59576672Execute EIP712338582902022-10-03 0:45:5814 mins ago0x27a9e32d0b1768dc8a77985a23544de565409c87 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.007858233157 37.000292665
0xba856438815cce87c9a1a6f1182569e1021a6950d45e807e7eb29f84a98c346bExecute EIP712338582812022-10-03 0:45:4014 mins ago0x0e935011582070a7c1873b5af9b81222fffbbe50 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.007113759077 39.680487502
0xaf9f29920039f01b2291cbdb7f0090ad8cd5498614d396efd2081e25b838d5d4Execute EIP712338582672022-10-03 0:45:1215 mins ago0xdd1ec40cb36286e1f892b4dc3943026f580f4bb9 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.00709975957 37.030567269
0xc4fb14a4418d5ee0477ffac813af3a1a62634b8538859a7804be11212f98d36bExecute EIP712338582392022-10-03 0:44:1216 mins ago0x2d7813a2e158b1615599e98ece851b29ad30d9db IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.007485376956 35.241389981
0xd9e6d43eba49e31a59779de639552d8f92a30fed315799269f7fa3d0b69faa90Execute EIP712338582322022-10-03 0:43:5816 mins ago0x6ebb85227f06bf1561da6578ed75acfa35872183 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.008511458895 36.623074588
0x5017527a11e940ba3d88b2666adb2a16e9e59a0dd1a2cbd07b083657afb07afeExecute EIP712338582262022-10-03 0:43:4616 mins ago0x736be00c9d24b7ef442c5efd4f48373640750120 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.006248400964 37.392735962
0x1ac5438c5133b9e3eef0296ff1dfb0c046da8a5144c767cc77009581e296eed8Execute EIP712338582162022-10-03 0:43:2616 mins ago0x2cbc450e04a6379d37f1b85655d1fc09bda3e6da IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.006697824298 40.181079356
0x609403f16ffb67d7c31b244522b09347a280505f358d1abcc3bda1b6525538edExecute EIP712338582102022-10-03 0:43:1416 mins ago0xa0a7b188603e050864ae5a5d562d4da63709f6c9 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.007341674697 40.94723082
0x17ce295095140953827445aaabd882674504092bf9dd16539489c36f2dc9e93dExecute EIP712338582082022-10-03 0:43:1017 mins ago0x7208deb6f9e75dab52a6e8ecb872fc32d3afbde8 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.005202714475 40.882880392
0x7f8e818f1a32defc302fd6f1c91fc3f3bc434c2ed7feed107e0b573331a3035eExecute EIP712338581992022-10-03 0:42:5217 mins ago0x531b77d33d3c654f9df6e228f11c5a0e0fb2c1ef IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.007763047593 40.490111428
0xac16f453a1ef415a317eba366b2d3a11ccfdcb8b770d24b1d047fd42c288e694Execute EIP712338581702022-10-03 0:41:5018 mins ago0x81ab1c751f6cc691002d34cc24730ed194afc0a8 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.007778883181 37.308076493
0xfde00b79e17282f15081edefddc9c2c1b18983aa5c616e162c0540da1b81b47cExecute EIP712338581032022-10-03 0:39:3220 mins ago0xbbb1860b76774f1bd06afc996801a8bb1343c652 IN  0xf0511f123164602042ab2bcf02111fa5d3fe97cd0 MATIC0.006223301653 37.242532428
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x80c2b02058d09D25A8fA7dbF449F26Da692a7387

Contract Name:
BiconomyForwarderV2

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 5 : BiconomyForwarderV2.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "./ForwardRequestTypesV2.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/**
 *
 * @title BiconomyForwarder
 *
 * @notice A trusted forwarder for Biconomy relayed meta transactions
 *
 * @dev - Inherits Forward Request structs from Forward Request Types
 * @dev - Verifies EIP712 signatures
 * @dev - Verifies traditional personalSign signatures
 * @dev - Implements 2D nonces... each Tx has a BatchId and a BatchNonce
 * @dev - Keeps track of highest BatchId used by a given address, to assist in encoding of transactions client-side
 * @dev - maintains a list of verified domain seperators
 *
 */

 contract BiconomyForwarderV2 is ForwardRequestTypesV2, Ownable {
    using ECDSA for bytes32;

    mapping(bytes32 => bool) public domains;

    uint256 chainId;

    string public constant EIP712_DOMAIN_TYPE = "EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)";

    //@review
    bytes32 public constant REQUEST_TYPEHASH = keccak256(bytes("ForwardRequest(address from,address to,uint256 txGas,uint256 batchId,uint256 batchNonce,uint256 deadline,bytes data)"));

    //@review and rename
    bytes32 public constant FORWARD_REQUEST_TYPEHASH = keccak256(bytes("ERC20ForwardRequest(address from,address to,address token,uint256 txGas,uint256 tokenGasPrice,uint256 batchId,uint256 batchNonce,uint256 deadline,bytes data)"));

    //Sandbox use case
    bytes32 public constant CUSTOM_FORWARD_REQUEST_TYPEHASH = keccak256(bytes("CustomForwardRequest(string warning,string info,string action,ERC20ForwardRequest request)ERC20ForwardRequest(address from,address to,address token,uint256 txGas,uint256 tokenGasPrice,uint256 batchId,uint256 batchNonce,uint256 deadline,bytes data)"));

    mapping(address => mapping(uint256 => uint256)) nonces;

    constructor(
    ) public {
        uint256 id;
        assembly {
            id := chainid()
        }
        chainId = id;
    }

    /**
     * @dev registers domain seperators, maintaining that all domain seperators used for EIP712 forward requests use...
     * ... the address of this contract and the chainId of the chain this contract is deployed to
     * @param name : name of dApp/dApp fee proxy
     * @param version : version of dApp/dApp fee proxy
     */
    function registerDomainSeparator(string calldata name, string calldata version) external onlyOwner{
        uint256 id;
        /* solhint-disable-next-line no-inline-assembly */
        assembly {
            id := chainid()
        }

        bytes memory domainValue = abi.encode(
            keccak256(bytes(EIP712_DOMAIN_TYPE)),
            keccak256(bytes(name)),
            keccak256(bytes(version)),
            address(this),
            bytes32(id));

        bytes32 domainHash = keccak256(domainValue);

        domains[domainHash] = true;
        emit DomainRegistered(domainHash, domainValue);
    }

    event DomainRegistered(bytes32 indexed domainSeparator, bytes domainValue);

    event MetaTransactionExecuted(address indexed userAddress, address indexed relayerAddress, bytes indexed functionSignature);

    /**
     * @dev returns a value from the nonces 2d mapping
     * @param from : the user address
     * @param batchId : the key of the user's batch being queried
     * @return nonce : the number of transaction made within said batch
     */
    function getNonce(address from, uint256 batchId)
    public view
    returns (uint256) {
        return nonces[from][batchId];
    }

    //TODO
    //@review if new read method is needed for Custom
    /**
     * @dev an external function which exposes the internal _verifySigEIP712 method
     * @param req : request being verified
     * @param domainSeparator : the domain separator presented to the user when signing
     * @param sig : the signature generated by the user's wallet
     */
    function verifyEIP712(
        ERC20ForwardRequest calldata req,
        bytes32 domainSeparator,
        bytes calldata sig)
    external view {
        _verifySigEIP712(req, domainSeparator, sig);
    }

    /**
     * @dev verifies the call is valid by calling _verifySigEIP712
     * @dev executes the forwarded call if valid
     * @dev updates the nonce after
     * @param req : ERC20 forward request being executed
     * @param domainSeparator : the domain separator presented to the user when signing
     * @param sig : the signature generated by the user's wallet
     * @return success : false if call fails. true otherwise
     * @return ret : any return data from the call
     */
    function executeEIP712(
        ERC20ForwardRequest calldata req,
        bytes32 domainSeparator,
        bytes calldata sig
    )
    external 
    returns (bool success, bytes memory ret) {
        _verifySigEIP712(req,domainSeparator,sig);
        _updateNonce(req);
        /* solhint-disable-next-line avoid-low-level-calls */
         (success,ret) = req.to.call{gas : req.txGas}(abi.encodePacked(req.data, req.from));
         // Validate that the relayer has sent enough gas for the call.
        // See https://ronan.eth.link/blog/ethereum-gas-dangers/
        assert(gasleft() > req.txGas / 63);
        _verifyCallResult(success,ret,"Forwarded call to destination did not succeed");
        emit MetaTransactionExecuted(req.from, msg.sender, req.data);
    }

    /**
     * @dev verifies the call is valid by calling _verifySigEIP712Custom
     * @dev executes the forwarded call if valid
     * @dev updates the nonce after
     * @param req : Custom ERC20 forward request being executed
     * @param domainSeparator : the domain separator presented to the user when signing
     * @param sig : the signature generated by the user's wallet
     * @return success : false if call fails. true otherwise
     * @return ret : any return data from the call
     */
    function executeEIP712Custom(
        CustomForwardRequest calldata req,
        bytes32 domainSeparator,
        bytes calldata sig
    )
    external 
    returns (bool success, bytes memory ret) {
        _verifySigEIP712Custom(req,domainSeparator,sig);
        _updateNonceCustom(req);
        /* solhint-disable-next-line avoid-low-level-calls */
         (success,ret) = req.request.to.call{gas : req.request.txGas}(abi.encodePacked(req.request.data, req.request.from));
         // Validate that the relayer has sent enough gas for the call.
        // See https://ronan.eth.link/blog/ethereum-gas-dangers/
        assert(gasleft() > req.request.txGas / 63);
        _verifyCallResult(success,ret,"Forwarded call to destination did not succeed");
        emit MetaTransactionExecuted(req.request.from, msg.sender, req.request.data);
    }

    /**
     * @dev an external function which exposes the internal _verifySigPersonSign method
     * @param req : request being verified
     * @param sig : the signature generated by the user's wallet
     */
    function verifyPersonalSign(
        ERC20ForwardRequest calldata req,
        bytes calldata sig)
    external view {
        _verifySigPersonalSign(req, sig);
    }

    /**
     * @dev verifies the call is valid by calling _verifySigPersonalSign
     * @dev executes the forwarded call if valid
     * @dev updates the nonce after
     * @param req : ERC20 forward request being executed
     * @param sig : the signature generated by the user's wallet
     * @return success : false if call fails. true otherwise
     * @return ret : any return data from the call
     */
    function executePersonalSign(ERC20ForwardRequest calldata req,bytes calldata sig)
    external 
    returns(bool success, bytes memory ret){
        _verifySigPersonalSign(req, sig);
        _updateNonce(req);
        (success,ret) = req.to.call{gas : req.txGas}(abi.encodePacked(req.data, req.from));
        // Validate that the relayer has sent enough gas for the call.
        // See https://ronan.eth.link/blog/ethereum-gas-dangers/
        assert(gasleft() > req.txGas / 63);
        _verifyCallResult(success,ret,"Forwarded call to destination did not succeed");
        emit MetaTransactionExecuted(req.from, msg.sender, req.data);
    }

    /**
     * @dev Increments the nonce of given user/batch pair
     * @dev Updates the highestBatchId of the given user if the request's batchId > current highest
     * @dev only intended to be called post call execution
     * @param req : ERC20 forward request that was executed
     */
    function _updateNonce(ERC20ForwardRequest calldata req) internal {
        nonces[req.from][req.batchId]++;
    }
    
    /**
     * @dev Increments the nonce of given user/batch pair
     * @dev Updates the highestBatchId of the given user if the request's batchId > current highest
     * @dev only intended to be called post call execution
     * @param req : ERC20 custom forward request that was executed
     */
    function _updateNonceCustom(CustomForwardRequest calldata req) internal {
        nonces[req.request.from][req.request.batchId]++;
    }

    /**
     * @dev verifies the domain separator used has been registered via registerDomainSeparator()
     * @dev recreates the 32 byte hash signed by the user's wallet (as per EIP712 specifications)
     * @dev verifies the signature using Open Zeppelin's ECDSA library
     * @dev signature valid if call doesn't throw
     *
     * @param req : ERC20 forward request being executed
     * @param domainSeparator : the domain separator presented to the user when signing
     * @param sig : the signature generated by the user's wallet
     *
     */
    function _verifySigEIP712(
        ERC20ForwardRequest calldata req,
        bytes32 domainSeparator,
        bytes memory sig)
    internal
    view
    {   
        uint256 id;
        /* solhint-disable-next-line no-inline-assembly */
        assembly {
            id := chainid()
        }
        require(req.deadline == 0 || block.timestamp + 20 <= req.deadline, "request expired");
        require(domains[domainSeparator], "unregistered domain separator");
        require(chainId == id, "potential replay attack on the fork");
        bytes32 digest =
            keccak256(abi.encodePacked(
                "\x19\x01",
                domainSeparator,
                hashERC20ForwardRequest(req)
            ));
        require(digest.recover(sig) == req.from, "signature mismatch");
    }

    /**
     * @dev verifies the domain separator used has been registered via registerDomainSeparator()
     * @dev recreates the 32 byte hash signed by the user's wallet (as per EIP712 specifications)
     * @dev verifies the signature using Open Zeppelin's ECDSA library
     * @dev signature valid if call doesn't throw
     *
     * @param req : Custom ERC20 forward request being executed
     * @param domainSeparator : the domain separator presented to the user when signing
     * @param sig : the signature generated by the user's wallet
     *
     */
    function _verifySigEIP712Custom(
        CustomForwardRequest calldata req,
        bytes32 domainSeparator,
        bytes memory sig)
    internal
    view
    {   
        uint256 id;
        /* solhint-disable-next-line no-inline-assembly */
        assembly {
            id := chainid()
        }
        require(req.request.deadline == 0 || block.timestamp + 20 <= req.request.deadline, "request expired");
        require(domains[domainSeparator], "unregistered domain separator");
        require(chainId == id, "potential replay attack on the fork");
        bytes32 digest =
            keccak256(abi.encodePacked(
                "\x19\x01",
                domainSeparator,
                hashCustomForwardRequest(req)
            ));
        require(digest.recover(sig) == req.request.from, "signature mismatch");
    }


    function hashERC20ForwardRequest(ERC20ForwardRequest calldata request) internal view returns (bytes32) {
        return keccak256(abi.encode(
            FORWARD_REQUEST_TYPEHASH,
            request.from,
            request.to,
            request.token,
            request.txGas,
            request.tokenGasPrice,
            request.batchId,
            nonces[request.from][request.batchId],
            request.deadline,
            keccak256(request.data)
        ));
    }

    function hashCustomForwardRequest(CustomForwardRequest calldata req) internal view returns (bytes32) {
        return keccak256(abi.encode(
            CUSTOM_FORWARD_REQUEST_TYPEHASH,
            keccak256(bytes(req.warning)),
            keccak256(bytes(req.info)),
            keccak256(bytes(req.action)),
            hashERC20ForwardRequest(req.request) 
        ));
    }

    /**
     * @dev encodes a 32 byte data string (presumably a hash of encoded data) as per eth_sign
     *
     * @param hash : hash of encoded data that signed by user's wallet using eth_sign
     * @return input hash encoded to matched what is signed by the user's key when using eth_sign*/
    function prefixed(bytes32 hash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev recreates the 32 byte hash signed by the user's wallet
     * @dev verifies the signature using Open Zeppelin's ECDSA library
     * @dev signature valid if call doesn't throw
     *
     * @param req : ERC20 forward request being executed
     * @param sig : the signature generated by the user's wallet
     *
     */
    function _verifySigPersonalSign(
        ERC20ForwardRequest calldata req,
        bytes memory sig)
    internal
    view
    {
        require(req.deadline == 0 || block.timestamp + 20 <= req.deadline, "request expired");
        bytes32 digest = prefixed(keccak256(abi.encodePacked(
            req.from,
            req.to,
            req.token,
            req.txGas,
            req.tokenGasPrice,
            req.batchId,
            nonces[req.from][req.batchId],
            req.deadline,
            keccak256(req.data)
        )));
        require(digest.recover(sig) == req.from, "signature mismatch");
    }

    /**
     * @dev verifies the call result and bubbles up revert reason for failed calls
     *
     * @param success : outcome of forwarded call
     * @param returndata : returned data from the frowarded call
     * @param errorMessage : fallback error message to show 
     */
     function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure {
        if (!success) {
            // 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 2 of 5 : ECDSA.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 27)
        }
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 3 of 5 : ForwardRequestTypesV2.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;


/* deadline can be removed : GSN reference https://github.com/opengsn/gsn/blob/master/contracts/forwarder/IForwarder.sol (Saves 250 more gas)*/
/**
* @title ForwardRequestTypes 
* @notice specifies structures required by Forwarders to verify structured signatures.
* @notice This contract defines a struct which both ERC20Forwarder and BiconomyForwarder inherit. ERC20ForwardRequest includes all the fields present in the GSN V2 ForwardRequest struct, 
* but adds the following :
* address token : address of the token to pay for gas fees. For gasless transactions token address will be 0 address
* uint256 tokenGasPrice : gas price in the context of fee token
* uint256 txGas : gas to be supplied for recipient method call
* uint256 batchNonce : used for 2D nonces
* uint256 deadline 
* @dev Fields are placed in type order, to minimise storage used when executing transactions.
*/
contract ForwardRequestTypesV2 {

/*allow the EVM to optimize for this, 
ensure that you try to order your storage variables and struct members such that they can be packed tightly*/

    struct ForwardRequest {
        address from; 
        address to; 
        uint256 txGas;
        uint256 batchId; 
        uint256 batchNonce; 
        uint256 deadline; 
        bytes data;
    }

    struct ERC20ForwardRequest {
        address from; 
        address to; 
        address token; 
        uint256 txGas;
        uint256 tokenGasPrice;
        uint256 batchId; 
        uint256 batchNonce; 
        uint256 deadline; 
        bytes data;
    }

    //@review
    //should be SandBox Forward Request?
    struct CustomForwardRequest {
        string warning; //optional
        string info;
        string action;
        ERC20ForwardRequest request;
    }

     //For DAI and EIP2612 type Permits
     struct PermitRequest {
        address holder; 
        address spender;  
        uint256 value;
        uint256 nonce;
        uint256 expiry;
        bool allowed; 
        uint8 v;
        bytes32 r; 
        bytes32 s; 
    }

}

File 4 of 5 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 5 of 5 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

Settings
{
  "evmVersion": "berlin",
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"domainSeparator","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"domainValue","type":"bytes"}],"name":"DomainRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":true,"internalType":"address","name":"relayerAddress","type":"address"},{"indexed":true,"internalType":"bytes","name":"functionSignature","type":"bytes"}],"name":"MetaTransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"CUSTOM_FORWARD_REQUEST_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EIP712_DOMAIN_TYPE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FORWARD_REQUEST_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REQUEST_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"domains","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"txGas","type":"uint256"},{"internalType":"uint256","name":"tokenGasPrice","type":"uint256"},{"internalType":"uint256","name":"batchId","type":"uint256"},{"internalType":"uint256","name":"batchNonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ForwardRequestTypesV2.ERC20ForwardRequest","name":"req","type":"tuple"},{"internalType":"bytes32","name":"domainSeparator","type":"bytes32"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"executeEIP712","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"ret","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"warning","type":"string"},{"internalType":"string","name":"info","type":"string"},{"internalType":"string","name":"action","type":"string"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"txGas","type":"uint256"},{"internalType":"uint256","name":"tokenGasPrice","type":"uint256"},{"internalType":"uint256","name":"batchId","type":"uint256"},{"internalType":"uint256","name":"batchNonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ForwardRequestTypesV2.ERC20ForwardRequest","name":"request","type":"tuple"}],"internalType":"struct ForwardRequestTypesV2.CustomForwardRequest","name":"req","type":"tuple"},{"internalType":"bytes32","name":"domainSeparator","type":"bytes32"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"executeEIP712Custom","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"ret","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"txGas","type":"uint256"},{"internalType":"uint256","name":"tokenGasPrice","type":"uint256"},{"internalType":"uint256","name":"batchId","type":"uint256"},{"internalType":"uint256","name":"batchNonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ForwardRequestTypesV2.ERC20ForwardRequest","name":"req","type":"tuple"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"executePersonalSign","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"ret","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"batchId","type":"uint256"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"}],"name":"registerDomainSeparator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"txGas","type":"uint256"},{"internalType":"uint256","name":"tokenGasPrice","type":"uint256"},{"internalType":"uint256","name":"batchId","type":"uint256"},{"internalType":"uint256","name":"batchNonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ForwardRequestTypesV2.ERC20ForwardRequest","name":"req","type":"tuple"},{"internalType":"bytes32","name":"domainSeparator","type":"bytes32"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"verifyEIP712","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"txGas","type":"uint256"},{"internalType":"uint256","name":"tokenGasPrice","type":"uint256"},{"internalType":"uint256","name":"batchId","type":"uint256"},{"internalType":"uint256","name":"batchNonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ForwardRequestTypesV2.ERC20ForwardRequest","name":"req","type":"tuple"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"verifyPersonalSign","outputs":[],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b5061001a33610023565b46600255610073565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611dbf806100826000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80639563096811610097578063c3f28abd11610066578063c3f28abd146101fc578063c722f17714610211578063e630543314610244578063f2fde38b1461024c57600080fd5b806395630968146101c65780639c7b4592146101ce5780639e39b73e146101e1578063a41a03f2146101e957600080fd5b8063715018a6116100d3578063715018a61461014c5780638171e6321461015457806389535803146101675780638da5cb5b146101ab57600080fd5b806341706c4e146100fa5780634abec93d146101245780636e4cb07514610137575b600080fd5b61010d6101083660046117f0565b61025f565b60405161011b929190611928565b60405180910390f35b61010d610132366004611795565b61041a565b61014a610145366004611844565b6105fa565b005b61014a61063f565b61010d610162366004611844565b61067e565b61019d6101753660046116eb565b6001600160a01b03919091166000908152600360209081526040808320938352929052205490565b60405190815260200161011b565b6000546040516001600160a01b03909116815260200161011b565b61019d610837565b61014a6101dc36600461172c565b61085a565b61019d61097b565b61014a6101f73660046117f0565b61099e565b6102046109e5565b60405161011b919061194b565b61023461021f366004611714565b60016020526000908152604090205460ff1681565b604051901515815260200161011b565b61019d610a01565b61014a61025a3660046116ca565b610a25565b600060606102a4868686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ac092505050565b6102ad86610c30565b6102bd60408701602088016116ca565b6001600160a01b031660608701356102d96101008901896119ff565b6102e660208b018b6116ca565b6040516020016102f8939291906118e6565b60408051601f19818403018152908290526103129161190c565b60006040518083038160008787f1925050503d8060008114610350576040519150601f19603f3d011682016040523d82523d6000602084013e610355565b606091505b50909250905061036a603f6060880135611a88565b5a1161038657634e487b7160e01b600052600160045260246000fd5b6103a982826040518060600160405280602d8152602001611c66602d9139610c7f565b6103b76101008701876119ff565b6040516103c59291906118d6565b604051908190039020336103dc60208901896116ca565b6001600160a01b03167f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b60405160405180910390a494509492505050565b6000606061045f868686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cae92505050565b61046886610de0565b6104756060870187611a5a565b6104869060408101906020016116ca565b6001600160a01b031661049c6060880188611a5a565b606001358780606001906104b09190611a5a565b6104bf906101008101906119ff565b6104cc60608b018b611a5a565b6104da9060208101906116ca565b6040516020016104ec939291906118e6565b60408051601f19818403018152908290526105069161190c565b60006040518083038160008787f1925050503d8060008114610544576040519150601f19603f3d011682016040523d82523d6000602084013e610549565b606091505b509092509050603f61055e6060880188611a5a565b6060013561056c9190611a88565b5a1161058857634e487b7160e01b600052600160045260246000fd5b6105ab82826040518060600160405280602d8152602001611c66602d9139610c7f565b6105b86060870187611a5a565b6105c7906101008101906119ff565b6040516105d59291906118d6565b604051908190039020336105ec6060890189611a5a565b6103dc9060208101906116ca565b61063a8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e4b92505050565b505050565b6000546001600160a01b031633146106725760405162461bcd60e51b815260040161066990611987565b60405180910390fd5b61067c6000611010565b565b600060606106c28585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e4b92505050565b6106cb85610c30565b6106db60408601602087016116ca565b6001600160a01b031660608601356106f76101008801886119ff565b61070460208a018a6116ca565b604051602001610716939291906118e6565b60408051601f19818403018152908290526107309161190c565b60006040518083038160008787f1925050503d806000811461076e576040519150601f19603f3d011682016040523d82523d6000602084013e610773565b606091505b509092509050610788603f6060870135611a88565b5a116107a457634e487b7160e01b600052600160045260246000fd5b6107c782826040518060600160405280602d8152602001611c66602d9139610c7f565b6107d56101008601866119ff565b6040516107e39291906118d6565b604051908190039020336107fa60208801886116ca565b6001600160a01b03167f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b60405160405180910390a4935093915050565b6040518060c00160405280609d8152602001611bc9609d91398051906020012081565b6000546001600160a01b031633146108845760405162461bcd60e51b815260040161066990611987565b600046905060006040518060800160405280604f8152602001611b06604f91398051906020012086866040516108bb9291906118d6565b604051809103902085856040516108d39291906118d6565b604080519182900382206020830194909452810191909152606081019190915230608082015260a0810183905260c00160408051601f198184030181528282528051602080830191909120600081815260019283905293909320805460ff1916909117905592509081907f4bc68689cbe89a4a6333a3ab0a70093874da3e5bfb71e93102027f3f073687d89061096a90859061194b565b60405180910390a250505050505050565b6040518060a0016040528060748152602001611b55607491398051906020012081565b6109df848484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ac092505050565b50505050565b6040518060800160405280604f8152602001611b06604f913981565b60405180610120016040528060f78152602001611c9360f791398051906020012081565b6000546001600160a01b03163314610a4f5760405162461bcd60e51b815260040161066990611987565b6001600160a01b038116610ab45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610669565b610abd81611010565b50565b4660e08401351580610ae0575060e0840135610add426014611a70565b11155b610afc5760405162461bcd60e51b81526004016106699061195e565b60008381526001602052604090205460ff16610b5a5760405162461bcd60e51b815260206004820152601d60248201527f756e7265676973746572656420646f6d61696e20736570617261746f720000006044820152606401610669565b8060025414610b7b5760405162461bcd60e51b8152600401610669906119bc565b600083610b8786611060565b60405161190160f01b60208201526022810192909252604282015260620160408051601f1981840301815291905280516020918201209150610bcb908601866116ca565b6001600160a01b0316610bde828561119a565b6001600160a01b031614610c295760405162461bcd60e51b81526020600482015260126024820152710e6d2cedcc2e8eae4ca40dad2e6dac2e8c6d60731b6044820152606401610669565b5050505050565b60036000610c4160208401846116ca565b6001600160a01b031681526020808201929092526040908101600090812060a085013582529092528120805491610c7783611ad4565b919050555050565b8261063a57815115610c945781518083602001fd5b8060405162461bcd60e51b8152600401610669919061194b565b46610cbc6060850185611a5a565b60e001351580610ce65750610cd46060850185611a5a565b60e00135610ce3426014611a70565b11155b610d025760405162461bcd60e51b81526004016106699061195e565b60008381526001602052604090205460ff16610d605760405162461bcd60e51b815260206004820152601d60248201527f756e7265676973746572656420646f6d61696e20736570617261746f720000006044820152606401610669565b8060025414610d815760405162461bcd60e51b8152600401610669906119bc565b600083610d8d866111be565b60405161190160f01b60208201526022810192909252604282015260620160408051601f1981840301815291905280516020909101209050610dd26060860186611a5a565b610bcb9060208101906116ca565b60036000610df16060840184611a5a565b610dff9060208101906116ca565b6001600160a01b031681526020810191909152604001600090812090610e286060840184611a5a565b60a0013581526020019081526020016000206000815480929190610c7790611ad4565b60e08201351580610e6a575060e0820135610e67426014611a70565b11155b610e865760405162461bcd60e51b81526004016106699061195e565b6000610fa3610e9860208501856116ca565b610ea860408601602087016116ca565b610eb860608701604088016116ca565b6060870135608088013560a089013560036000610ed860208d018d6116ca565b6001600160a01b031681526020808201929092526040908101600090812060a08e0135825290925290205460e08b0135610f166101008d018d6119ff565b604051610f249291906118d6565b6040519081900381206bffffffffffffffffffffffff1960609a8b1b81166020840152988a1b891660348301529690981b9096166048880152605c870193909352607c860191909152609c85015260bc84015260dc83019190915260fc82015261011c016040516020818303038152906040528051906020012061128e565b9050610fb260208401846116ca565b6001600160a01b0316610fc5828461119a565b6001600160a01b03161461063a5760405162461bcd60e51b81526020600482015260126024820152710e6d2cedcc2e8eae4ca40dad2e6dac2e8c6d60731b6044820152606401610669565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006040518060c00160405280609d8152602001611bc9609d9139805160209182012090611090908401846116ca565b6110a060408501602086016116ca565b6110b060608601604087016116ca565b6060860135608087013560a0880135600360006110d060208c018c6116ca565b6001600160a01b031681526020808201929092526040908101600090812060a08d0135825290925290205460e08a013561110e6101008c018c6119ff565b60405161111c9291906118d6565b60408051918290038220602083019b909b526001600160a01b03998a1690820152968816606088015296909416608086015260a085019290925260c084015260e0830152610100820152610120810191909152610140810191909152610160015b604051602081830303815290604052805190602001209050919050565b60008060006111a985856112c9565b915091506111b681611339565b509392505050565b600060405180610120016040528060f78152602001611c9360f7913980516020909101206111ec8380611a44565b6040516111fa9291906118d6565b6040519081900390206112106020850185611a44565b60405161121e9291906118d6565b60405180910390208480604001906112369190611a44565b6040516112449291906118d6565b60405190819003902061126261125d6060880188611a5a565b611060565b6040805160208101969096528501939093526060840191909152608083015260a082015260c00161117d565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c0161117d565b6000808251604114156113005760208301516040840151606085015160001a6112f48782858561153a565b94509450505050611332565b82516040141561132a576020830151604084015161131f868383611627565b935093505050611332565b506000905060025b9250929050565b600081600481111561135b57634e487b7160e01b600052602160045260246000fd5b14156113645750565b600181600481111561138657634e487b7160e01b600052602160045260246000fd5b14156113d45760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610669565b60028160048111156113f657634e487b7160e01b600052602160045260246000fd5b14156114445760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610669565b600381600481111561146657634e487b7160e01b600052602160045260246000fd5b14156114bf5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610669565b60048160048111156114e157634e487b7160e01b600052602160045260246000fd5b1415610abd5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610669565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611571575060009050600361161e565b8460ff16601b1415801561158957508460ff16601c14155b1561159a575060009050600461161e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156115ee573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166116175760006001925092505061161e565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b016116488782888561153a565b935093505050935093915050565b80356001600160a01b038116811461166d57600080fd5b919050565b60008083601f840112611683578182fd5b50813567ffffffffffffffff81111561169a578182fd5b60208301915083602082850101111561133257600080fd5b600061012082840312156116c4578081fd5b50919050565b6000602082840312156116db578081fd5b6116e482611656565b9392505050565b600080604083850312156116fd578081fd5b61170683611656565b946020939093013593505050565b600060208284031215611725578081fd5b5035919050565b60008060008060408587031215611741578182fd5b843567ffffffffffffffff80821115611758578384fd5b61176488838901611672565b9096509450602087013591508082111561177c578384fd5b5061178987828801611672565b95989497509550505050565b600080600080606085870312156117aa578384fd5b843567ffffffffffffffff808211156117c1578586fd5b90860190608082890312156117d4578586fd5b909450602086013593506040860135908082111561177c578384fd5b60008060008060608587031215611805578384fd5b843567ffffffffffffffff8082111561181c578586fd5b611828888389016116b2565b955060208701359450604087013591508082111561177c578384fd5b600080600060408486031215611858578283fd5b833567ffffffffffffffff8082111561186f578485fd5b61187b878388016116b2565b94506020860135915080821115611890578384fd5b5061189d86828701611672565b9497909650939450505050565b600081518084526118c2816020860160208601611aa8565b601f01601f19169290920160200192915050565b8183823760009101908152919050565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b6000825161191e818460208701611aa8565b9190910192915050565b821515815260406020820152600061194360408301846118aa565b949350505050565b6020815260006116e460208301846118aa565b6020808252600f908201526e1c995c5d595cdd08195e1c1a5c9959608a1b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526023908201527f706f74656e7469616c207265706c61792061747461636b206f6e2074686520666040820152626f726b60e81b606082015260800190565b6000808335601e19843603018112611a15578283fd5b83018035915067ffffffffffffffff821115611a2f578283fd5b60200191503681900382131561133257600080fd5b6000808335601e19843603018112611a15578182fd5b6000823561011e1983360301811261191e578182fd5b60008219821115611a8357611a83611aef565b500190565b600082611aa357634e487b7160e01b81526012600452602481fd5b500490565b60005b83811015611ac3578181015183820152602001611aab565b838111156109df5750506000910152565b6000600019821415611ae857611ae8611aef565b5060010190565b634e487b7160e01b600052601160045260246000fdfe454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c6164647265737320766572696679696e67436f6e74726163742c627974657333322073616c7429466f72776172645265717565737428616464726573732066726f6d2c6164647265737320746f2c75696e743235362074784761732c75696e7432353620626174636849642c75696e743235362062617463684e6f6e63652c75696e7432353620646561646c696e652c62797465732064617461294552433230466f72776172645265717565737428616464726573732066726f6d2c6164647265737320746f2c6164647265737320746f6b656e2c75696e743235362074784761732c75696e7432353620746f6b656e47617350726963652c75696e7432353620626174636849642c75696e743235362062617463684e6f6e63652c75696e7432353620646561646c696e652c6279746573206461746129466f727761726465642063616c6c20746f2064657374696e6174696f6e20646964206e6f742073756363656564437573746f6d466f72776172645265717565737428737472696e67207761726e696e672c737472696e6720696e666f2c737472696e6720616374696f6e2c4552433230466f7277617264526571756573742072657175657374294552433230466f72776172645265717565737428616464726573732066726f6d2c6164647265737320746f2c6164647265737320746f6b656e2c75696e743235362074784761732c75696e7432353620746f6b656e47617350726963652c75696e7432353620626174636849642c75696e743235362062617463684e6f6e63652c75696e7432353620646561646c696e652c6279746573206461746129a26469706673582212205fbc05e07af55f4c17f97fd5da997389fe94192a5be1e03a1620cd754a89d82a64736f6c63430008040033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
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.