Contract 0x64CD353384109423a966dCd3Aa30D884C9b2E057 9

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x45b9d484ef244ca821b6ffc7e3d6938ec1098636ca4c0f0118bc2985b89a796dExecute EIP712551962762023-02-06 13:03:4710 hrs 7 mins ago0xc2cbad9f0cba3b871e8a160cc945d720e75252ff IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.700987664711
0x4373b7a0be517dd5d3a4168fee49805d8cd10465d70b276ac47752161d96bddeExecute EIP712551910362023-02-06 10:56:5712 hrs 14 mins ago0xbc6c2d12f7d986dd551a6b28a547dc2a0319a3f7 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.009006791666
0x7fde0430ce1ab72a2428d3c6b65a6a794692f4cfca9cc525292376778726ce5aExecute EIP712551909152023-02-06 10:53:3812 hrs 17 mins ago0xbc6c2d12f7d986dd551a6b28a547dc2a0319a3f7 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.00864296
0x9e1b465278e339beaf8f812c84f11e1a9b5615f689e8a17f954148cb7d786195Execute EIP712549884492023-02-03 12:24:293 days 10 hrs ago0xd52f9ec96996e33fc705670a63b2e0a34fe91aa2 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.081731436692
0x64dd3ce83deba9efe4414bccc00608c2fcb5cc991c989f09d6303bbb97ae5473Execute EIP712549742392023-02-03 7:52:393 days 15 hrs ago0xc2cbad9f0cba3b871e8a160cc945d720e75252ff IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.019506844023
0x87503c7e06f13b0e9a62051b54f8b8db0b7d1b54e21ab51d2a0ffca6f9cb2703Execute EIP712549742382023-02-03 7:52:383 days 15 hrs ago0x9d9b19b6bf385d50b1895b66328b8aa95cdbd460 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.033772602201
0xe370361c999c5d53862258f1332b23e7ab5fc1b76e92ecc5ea539628befa5b83Execute EIP712549736362023-02-03 7:40:153 days 15 hrs ago0x0a57012d1378a8a25e03dd1d66215557458bb241 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.135636261264
0xc7c1c827422cca8218762f680c143ea35e4e861163af6318ba6c12cf7fed936fExecute EIP712549728962023-02-03 7:25:473 days 15 hrs ago0x327d372f9b1d7ada2565c777b51f6f73b7b9279a IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.062262002318
0xe5031bd74240d558161941954d0875b4d860f8a3675cfc31cd14cdd12c05d485Execute EIP712549721872023-02-03 7:11:413 days 15 hrs ago0xb5dad764c4ad8f2b1a99d330046bdf71fbab1a9f IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.062471983073
0x0762a80b81e46f6e0d44707fdd715b4f457aeb950179cfa370052f5a1531cd4bExecute EIP712549685272023-02-03 5:58:393 days 17 hrs ago0xd3c3c84c55905834fb374c4379f8cf6636a233a8 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.147311640888
0x42aa022514b5ce4371553cbc6b0cfe5c7b59a543a8a20918e4bae3419d89fb78Execute EIP712525706412022-12-20 5:48:3448 days 17 hrs ago0xf0584bbeda83798a8680d145c1b5a805f9659df1 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.028819359439
0xa56decc6fe7b4266f97c5aa74686278029e890f10b34d576140fc675bcc6cfebExecute EIP712517759582022-12-02 12:07:0866 days 11 hrs ago0xf0584bbeda83798a8680d145c1b5a805f9659df1 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.012573792
0x7c1f156f50ac691f8662d387fc2cd9fb85d92c153f29eae96b3b272f0b240657Execute Personal...517370702022-12-01 21:39:5767 days 1 hr ago0x327d372f9b1d7ada2565c777b51f6f73b7b9279a IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.018816001059
0x76bd8ea92b98a644841a923819bc399dbf7c4901546dc45235c2e45863ffb3dcExecute Personal...517298622022-12-01 18:48:5667 days 4 hrs ago0x2ea96239e348e28c0a2edf22aaacc547c2ebce55 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.011362017703
0x88fc5d4b9bb10108c0b44f61369498aa2769ffdefa6d86dff589bec80419ee43Execute Personal...517294992022-12-01 18:41:0167 days 4 hrs ago0x30a33432858db2728e622f86609c1a1edc0da750 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.017753472
0x37bd1a9120a2aec391d492a11e78ac61bb384c564909a06c2c99c7d526571443Execute Personal...517290382022-12-01 18:29:5867 days 4 hrs ago0xf0584bbeda83798a8680d145c1b5a805f9659df1 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.017811163622
0xd8741aec438ab160ebc81f1bde9b85c20b1913547a6a51591de784a9b9c6037cExecute Personal...517284342022-12-01 18:12:5367 days 4 hrs ago0x9d9b19b6bf385d50b1895b66328b8aa95cdbd460 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.017751888
0x59c52c445745186d50beccde90e0499c8c3389f81bc65396e4ba1833f0457cffExecute Personal...517275202022-12-01 17:51:1767 days 5 hrs ago0x0a57012d1378a8a25e03dd1d66215557458bb241 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.017753472
0x938427f41de30d031181105d7f97d5b8be0825712a6d6e00163c25f5af3f3fedExecute Personal...517273902022-12-01 17:48:5067 days 5 hrs ago0x327d372f9b1d7ada2565c777b51f6f73b7b9279a IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.013129067775
0x67f30f099a2851b4e49e7ad04048ad8e81f62c2642b696b766a54eb32eb6b354Execute Personal...517272832022-12-01 17:46:5967 days 5 hrs ago0x7b031f4da991b412734b46877486088a385c2912 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.017751888
0x34ffa83fce1f4d76bf6565f49e1c1eb5ecd9762be04332261d6907b478f967a5Execute Personal...517260292022-12-01 17:14:5267 days 5 hrs ago0x30a33432858db2728e622f86609c1a1edc0da750 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.018577259999
0x93c2b299e9eb268ae18fae5cfd9cc2566854c1091eb68d52f5c8649a80ca86d3Execute Personal...517257832022-12-01 17:07:4067 days 6 hrs ago0x7208deb6f9e75dab52a6e8ecb872fc32d3afbde8 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.016903862414
0xa7f7792f75c8592410dbf34e8a1b8139dd3b00da8b3f49018eb24622647ed3a2Execute Personal...517252542022-12-01 16:54:2467 days 6 hrs ago0x9d9b19b6bf385d50b1895b66328b8aa95cdbd460 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.016751676438
0xe7e3ded601b555355afc3127917cee569c2c8433994678ef2d916997cdc18beaExecute Personal...517246382022-12-01 16:41:2967 days 6 hrs ago0x9bc6af5583b5278f3c50ed238e5c0fe8c126eb36 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.01820247034
0x69c00e08a8a0cb41c209979ecc7aeec1d463be6462b03c81d91e055d683c1637Execute Personal...517244872022-12-01 16:38:1967 days 6 hrs ago0x2ea96239e348e28c0a2edf22aaacc547c2ebce55 IN  0x64cd353384109423a966dcd3aa30d884c9b2e0570 FTM0.019182933043
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0x23a31b491f9f61427f7025873d2fff4d598e8121cd215790150d5b37cf2e19cc293116992022-01-28 19:24:28374 days 3 hrs ago 0x2b241cbe6b455e08ade78a7ccc42de2403d7b566  Contract Creation0 FTM
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BiconomyForwarder

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 : BiconomyForwarder.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "./ForwardRequestTypes.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
 *
 */

 //@review if experimental abiCoder is necessary for structs we need in calldata
 contract BiconomyForwarder is ForwardRequestTypes, 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 and rename
    bytes32 public constant REQUEST_TYPEHASH = keccak256(bytes("ERC20ForwardRequest(address from,address to,address token,uint256 txGas,uint256 tokenGasPrice,uint256 batchId,uint256 batchNonce,uint256 deadline,bytes data)"));

    //@review
    //Could add more type hash and rename above one if multiple executeEIP712 is planned to be supported

    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];
    }

    /**
     * @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 : 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 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 : 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 : request that was executed
     */
    function _updateNonce(ERC20ForwardRequest calldata req) internal {
        nonces[req.from][req.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 : 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,
                keccak256(abi.encode(REQUEST_TYPEHASH,
                            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 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 : 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 : ForwardRequestTypes.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 ForwardRequestTypes {

/*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 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 ForwardRequest {
        string info;
        string warning; //optional
        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":"EIP712_DOMAIN_TYPE","outputs":[{"internalType":"string","name":"","type":"string"}],"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 ForwardRequestTypes.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":"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 ForwardRequestTypes.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 ForwardRequestTypes.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 ForwardRequestTypes.ERC20ForwardRequest","name":"req","type":"tuple"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"verifyPersonalSign","outputs":[],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b5061001a33610023565b46600255610073565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611706806100826000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80639c7b4592116100715780639c7b4592146101725780639e39b73e14610185578063a41a03f21461018d578063c3f28abd146101a0578063c722f177146101b5578063f2fde38b146101e857600080fd5b806341706c4e146100b95780636e4cb075146100e3578063715018a6146100f85780638171e6321461010057806389535803146101135780638da5cb5b14610157575b600080fd5b6100cc6100c736600461133a565b6101fb565b6040516100da929190611472565b60405180910390f35b6100f66100f136600461138e565b6103b6565b005b6100f66103fb565b6100cc61010e36600461138e565b61043a565b610149610121366004611290565b6001600160a01b03919091166000908152600360209081526040808320938352929052205490565b6040519081526020016100da565b6000546040516001600160a01b0390911681526020016100da565b6100f66101803660046112d1565b6105f3565b610149610714565b6100f661019b36600461133a565b610737565b6101a861077e565b6040516100da9190611495565b6101d86101c33660046112b9565b60016020526000908152604090205460ff1681565b60405190151581526020016100da565b6100f66101f636600461126f565b61079a565b60006060610240868686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083592505050565b61024986610b47565b610259604087016020880161126f565b6001600160a01b031660608701356102756101008901896114dd565b61028260208b018b61126f565b60405160200161029493929190611430565b60408051601f19818403018152908290526102ae91611456565b60006040518083038160008787f1925050503d80600081146102ec576040519150601f19603f3d011682016040523d82523d6000602084013e6102f1565b606091505b509092509050610306603f606088013561153a565b5a1161032257634e487b7160e01b600052600160045260246000fd5b61034582826040518060600160405280602d81526020016116a4602d9139610b96565b6103536101008701876114dd565b604051610361929190611420565b60405190819003902033610378602089018961126f565b6001600160a01b03167f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b60405160405180910390a494509492505050565b6103f68383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610bc592505050565b505050565b6000546001600160a01b0316331461042e5760405162461bcd60e51b8152600401610425906114a8565b60405180910390fd5b6104386000610dfa565b565b6000606061047e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610bc592505050565b61048785610b47565b610497604086016020870161126f565b6001600160a01b031660608601356104b36101008801886114dd565b6104c060208a018a61126f565b6040516020016104d293929190611430565b60408051601f19818403018152908290526104ec91611456565b60006040518083038160008787f1925050503d806000811461052a576040519150601f19603f3d011682016040523d82523d6000602084013e61052f565b606091505b509092509050610544603f606087013561153a565b5a1161056057634e487b7160e01b600052600160045260246000fd5b61058382826040518060600160405280602d81526020016116a4602d9139610b96565b6105916101008601866114dd565b60405161059f929190611420565b604051908190039020336105b6602088018861126f565b6001600160a01b03167f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b60405160405180910390a4935093915050565b6000546001600160a01b0316331461061d5760405162461bcd60e51b8152600401610425906114a8565b600046905060006040518060800160405280604f81526020016115b8604f9139805190602001208686604051610654929190611420565b6040518091039020858560405161066c929190611420565b604080519182900382206020830194909452810191909152606081019190915230608082015260a0810183905260c00160408051601f198184030181528282528051602080830191909120600081815260019283905293909320805460ff1916909117905592509081907f4bc68689cbe89a4a6333a3ab0a70093874da3e5bfb71e93102027f3f073687d890610703908590611495565b60405180910390a250505050505050565b6040518060c00160405280609d8152602001611607609d91398051906020012081565b610778848484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061083592505050565b50505050565b6040518060800160405280604f81526020016115b8604f913981565b6000546001600160a01b031633146107c45760405162461bcd60e51b8152600401610425906114a8565b6001600160a01b0381166108295760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610425565b61083281610dfa565b50565b4660e08401351580610855575060e0840135610852426014611522565b11155b6108935760405162461bcd60e51b815260206004820152600f60248201526e1c995c5d595cdd08195e1c1a5c9959608a1b6044820152606401610425565b60008381526001602052604090205460ff166108f15760405162461bcd60e51b815260206004820152601d60248201527f756e7265676973746572656420646f6d61696e20736570617261746f720000006044820152606401610425565b806002541461094e5760405162461bcd60e51b815260206004820152602360248201527f706f74656e7469616c207265706c61792061747461636b206f6e2074686520666044820152626f726b60e81b6064820152608401610425565b6000836040518060c00160405280609d8152602001611607609d913980516020918201209061097f9088018861126f565b61098f6040890160208a0161126f565b61099f60608a0160408b0161126f565b89606001358a608001358b60a00135600360008e60000160208101906109c5919061126f565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008e60a001358152602001908152602001600020548d60e001358e806101000190610a1191906114dd565b604051610a1f929190611420565b60408051918290038220602083019b909b526001600160a01b03998a1690820152968816606088015296909416608086015260a085019290925260c084015260e08301526101008201526101208101919091526101408101919091526101600160405160208183030381529060405280519060200120604051602001610abc92919061190160f01b81526002810192909252602282015260420190565b60408051601f1981840301815291905280516020918201209150610ae29086018661126f565b6001600160a01b0316610af58285610e4a565b6001600160a01b031614610b405760405162461bcd60e51b81526020600482015260126024820152710e6d2cedcc2e8eae4ca40dad2e6dac2e8c6d60731b6044820152606401610425565b5050505050565b60036000610b58602084018461126f565b6001600160a01b031681526020808201929092526040908101600090812060a085013582529092528120805491610b8e83611586565b919050555050565b826103f657815115610bab5781518083602001fd5b8060405162461bcd60e51b81526004016104259190611495565b60e08201351580610be4575060e0820135610be1426014611522565b11155b610c225760405162461bcd60e51b815260206004820152600f60248201526e1c995c5d595cdd08195e1c1a5c9959608a1b6044820152606401610425565b6000610d8d610c34602085018561126f565b610c44604086016020870161126f565b610c54606087016040880161126f565b6060870135608088013560a089013560036000610c7460208d018d61126f565b6001600160a01b031681526020808201929092526040908101600090812060a08e0135825290925290205460e08b0135610cb26101008d018d6114dd565b604051610cc0929190611420565b6040519081900381206bffffffffffffffffffffffff1960609a8b1b81166020840152988a1b891660348301529690981b9096166048880152605c870193909352607c860191909152609c85015260bc84015260dc83019190915260fc82015261011c01604051602081830303815290604052805190602001206040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b9050610d9c602084018461126f565b6001600160a01b0316610daf8284610e4a565b6001600160a01b0316146103f65760405162461bcd60e51b81526020600482015260126024820152710e6d2cedcc2e8eae4ca40dad2e6dac2e8c6d60731b6044820152606401610425565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806000610e598585610e6e565b91509150610e6681610ede565b509392505050565b600080825160411415610ea55760208301516040840151606085015160001a610e99878285856110df565b94509450505050610ed7565b825160401415610ecf5760208301516040840151610ec48683836111cc565b935093505050610ed7565b506000905060025b9250929050565b6000816004811115610f0057634e487b7160e01b600052602160045260246000fd5b1415610f095750565b6001816004811115610f2b57634e487b7160e01b600052602160045260246000fd5b1415610f795760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610425565b6002816004811115610f9b57634e487b7160e01b600052602160045260246000fd5b1415610fe95760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610425565b600381600481111561100b57634e487b7160e01b600052602160045260246000fd5b14156110645760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610425565b600481600481111561108657634e487b7160e01b600052602160045260246000fd5b14156108325760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610425565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561111657506000905060036111c3565b8460ff16601b1415801561112e57508460ff16601c14155b1561113f57506000905060046111c3565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611193573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166111bc576000600192509250506111c3565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b016111ed878288856110df565b935093505050935093915050565b80356001600160a01b038116811461121257600080fd5b919050565b60008083601f840112611228578182fd5b50813567ffffffffffffffff81111561123f578182fd5b602083019150836020828501011115610ed757600080fd5b60006101208284031215611269578081fd5b50919050565b600060208284031215611280578081fd5b611289826111fb565b9392505050565b600080604083850312156112a2578081fd5b6112ab836111fb565b946020939093013593505050565b6000602082840312156112ca578081fd5b5035919050565b600080600080604085870312156112e6578182fd5b843567ffffffffffffffff808211156112fd578384fd5b61130988838901611217565b90965094506020870135915080821115611321578384fd5b5061132e87828801611217565b95989497509550505050565b6000806000806060858703121561134f578384fd5b843567ffffffffffffffff80821115611366578586fd5b61137288838901611257565b9550602087013594506040870135915080821115611321578384fd5b6000806000604084860312156113a2578283fd5b833567ffffffffffffffff808211156113b9578485fd5b6113c587838801611257565b945060208601359150808211156113da578384fd5b506113e786828701611217565b9497909650939450505050565b6000815180845261140c81602086016020860161155a565b601f01601f19169290920160200192915050565b8183823760009101908152919050565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b6000825161146881846020870161155a565b9190910192915050565b821515815260406020820152600061148d60408301846113f4565b949350505050565b60208152600061128960208301846113f4565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000808335601e198436030181126114f3578283fd5b83018035915067ffffffffffffffff82111561150d578283fd5b602001915036819003821315610ed757600080fd5b60008219821115611535576115356115a1565b500190565b60008261155557634e487b7160e01b81526012600452602481fd5b500490565b60005b8381101561157557818101518382015260200161155d565b838111156107785750506000910152565b600060001982141561159a5761159a6115a1565b5060010190565b634e487b7160e01b600052601160045260246000fdfe454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c6164647265737320766572696679696e67436f6e74726163742c627974657333322073616c74294552433230466f72776172645265717565737428616464726573732066726f6d2c6164647265737320746f2c6164647265737320746f6b656e2c75696e743235362074784761732c75696e7432353620746f6b656e47617350726963652c75696e7432353620626174636849642c75696e743235362062617463684e6f6e63652c75696e7432353620646561646c696e652c6279746573206461746129466f727761726465642063616c6c20746f2064657374696e6174696f6e20646964206e6f742073756363656564a26469706673582212202097c91bd976061fd913789ee0f58acc962494c391c5d4a2eda20081b94ff02264736f6c63430008040033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Validator ID :
0 FTM

Amount Staked
0

Amount Delegated
0

Staking Total
0

Staking Start Epoch
0

Staking Start Time
0

Proof of Importance
0

Origination Score
0

Validation Score
0

Active
0

Online
0

Downtime
0 s
Address Amount claimed Rewards Created On Epoch Created On
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.