Contract 0x549dbdffbd47bd5639f9348ebe82e63e2f9f777a 9

 
Txn Hash Method
Block
From
To
Value
0x774e434ec01e4c0cda8e54c7d35e30bb1ed7e0aa4cd4e2c2fdfdd9a15904f488Execute Offchain...1165294422024-02-23 3:07:412 days 19 hrs ago0x7db23fae20313ee90afd7c4b0e5ec9ad26d8e1c5 IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0005698877620.033720778
0x2dcf40b49f4bd5147f86ffae8521a9d65ff1f2dee90940fbaf0c90be654696faExecute Offchain...1164159812024-02-20 12:05:395 days 10 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0005357232920.099120551
0x74f7d2bf3eae61a05b18762a14f13cdf12fa72186dacccdee98aa6a32ffa31c3Execute Offchain...1149724702024-01-18 2:08:3738 days 20 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0005208996410.034955278
0xad44a0718e29d6f98f2754d3202854c0f80803a018192aecde32174708cff617Execute Offchain...1149644452024-01-17 21:41:0739 days 1 hr ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.000617795770.106742273
0x5a99eae9d10b44b4c4cd6e913f512f3bf78c4e5825c92e65ba1af84ad3aafbe2Execute Offchain...1148443902024-01-15 2:59:1741 days 19 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0004089345910.131033296
0x3ccff3e74403c4123c1c2664f218722a88e885c5e489000798b9cfa429b59db2Execute Offchain...1147438342024-01-12 19:07:2544 days 3 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0005497871270.140627875
0x37f6e53add0d4d2d042b872922e9652cd2838f7de9872f5483cae9eb02055b06Execute Offchain...1147203422024-01-12 6:04:2144 days 16 hrs ago0x09997af08ed4edcc6a932da468cd87cbda70b52a IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0005470386240.304530918
0xd272bc8b99956403e9ee825460b126684427ac27bd047f614a4d9cf14a2d3e22Execute Offchain...1146951242024-01-11 16:03:4545 days 6 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0011299096580.061890107
0xcb6cef5256e5c41d7b31dbebd9be16c3b1866b9ed1b653dbc2b3284604c826b3Execute Offchain...1145435352024-01-08 3:50:4748 days 18 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0004157998050.094188995
0xf30dcebf2154e671d188385fe6db2cf71f4f1da7871f97120dddcf7ccdebaafdExecute Offchain...1144313712024-01-05 13:31:5951 days 9 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0003713058730.157160631
0x188293fe8ce1528a39a72d42421b8f9e0fc40ec3965e5655076188e4046fe275Execute Offchain...1144189292024-01-05 6:37:1551 days 16 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0002147391520.096155726
0x58017bea8a4e92fd7d8a33dbb764ba9981a40fd806eb73d12471ed4b7aeb440dExecute Offchain...1143509952024-01-03 16:52:4753 days 5 hrs ago0x45adff4ddbb129d20b0690e24b43ec0653961ca3 IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0006551849860.040225584
0xaacb386cb65fa1d28536a586bcde7086ada764f4d7e0c48df67473430bef804eExecute Offchain...1143390272024-01-03 10:13:5153 days 12 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0004621928420.1530494
0x3f9c351b0f4b8bc8e80f63e16c104a8dbb873d4212211a6f7bc84023a1685aeaExecute Offchain...1141248602023-12-29 11:14:5758 days 11 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0004678224790.153289164
0x339d7590b14555a450f96e3a6656c838d3e245e36a5f521d5b5afa6862c592bdExecute Offchain...1140909282023-12-28 16:23:5359 days 6 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.000575686450.125537277
0x194e3e9e1412e8ec3173b7d4aafd92f0d73ec725c74929241e632b6b7ed9c716Execute Offchain...1140735582023-12-28 6:44:5359 days 15 hrs ago0x45adff4ddbb129d20b0690e24b43ec0653961ca3 IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0004530647010.032501016
0x66d9759a7854e5b6adc02190b72029be5f5c5a47fafabbff59856e767e99ae78Transfer Margin1138069372023-12-22 2:37:3165 days 20 hrs ago0x24aa1ad305f8e6de8e0fa2f4c249ac278fba9d7f IN  Synthetix: Perps V2 Proxy XRPPERP0 ETH0.0000607736440.005567055
0x28d5b3df891fbf79b466dde5aa30421f488aa97c051b4c7320ee43f318babbcdExecute Offchain...1134932702023-12-14 20:21:5773 days 2 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0007909378470.038411985
0xe989d9659fa7a2bb10411bba431c1dfa17b68ab12d764f2bb497b9724f456663Execute Offchain...1134913332023-12-14 19:17:2373 days 3 hrs ago0x29c8089edb60c72c402ceba3f5c5bafea4bbb604 IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0007864623170.278483011
0xc202016172a4b17d3cb2133cba26024e9d4d11c4d5d3a5f93b309c8b1cbae45cExecute Offchain...1134913322023-12-14 19:17:2173 days 3 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0007810633090.209735627
0x2d23e1f33908a4e99960d9df2d2f1873f1a9393e7bbd20468c50c2865447f91eExecute Offchain...1134878142023-12-14 17:20:0573 days 5 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0007003106280.131391372
0x507f912ed71aeead32999d11a4b55b76089bb8e36885ee6dbd8ac2f325bc0cbbExecute Offchain...1134828072023-12-14 14:33:1173 days 8 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0005511533550.038632947
0x8d6fe1a379ff761700b4bad2211320d2344c151652a6c3e313231d74dc82592eExecute Offchain...1134815762023-12-14 13:52:0973 days 8 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0007146568680.133922565
0xffedf03cc691677beebbdf8751dfb14e06c3df29b85fd60998c28d5f28c60d93Execute Offchain...1134476212023-12-13 19:00:1974 days 3 hrs ago0x29c8089edb60c72c402ceba3f5c5bafea4bbb604 IN  Synthetix: Perps V2 Proxy XRPPERP0.001 ETH0.0009933600051.007708887
0x23b6ebcdf0e0eb4a121e81dd8d8b9f1ca47fe51d861fb8abdca30e540e7904daExecute Offchain...1133890192023-12-12 10:26:5575 days 12 hrs ago0x0e118783aec093d97a4b7b4bb6023e0fd2e2dfeb IN  Synthetix: Perps V2 Proxy XRPPERP1 wei0.0006322625230.139980486
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x774e434ec01e4c0cda8e54c7d35e30bb1ed7e0aa4cd4e2c2fdfdd9a15904f4881165294422024-02-23 3:07:412 days 19 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0x2bdd5e1f2e052611b61b75e42bf3bb88b5737dcf78e90d727dbb88e5a70442c81164734212024-02-21 20:00:194 days 2 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0x2bdd5e1f2e052611b61b75e42bf3bb88b5737dcf78e90d727dbb88e5a70442c81164734212024-02-21 20:00:194 days 2 hrs ago 0x87cdbbcb50feeef407b083659ab74b0547788c59 Synthetix: Perps V2 Proxy XRPPERP1 wei
0x802d3474a2446b688255968b07babceb6ef141eff1ef63d36657acef27c5bc591164405622024-02-21 1:45:014 days 20 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0x802d3474a2446b688255968b07babceb6ef141eff1ef63d36657acef27c5bc591164405622024-02-21 1:45:014 days 20 hrs ago 0x30609910c6fbff5bb7afa0732ccfefa6419654f1 Synthetix: Perps V2 Proxy XRPPERP1 wei
0xc96071d9168a68e26a756ddecf9477d5b620212f44d90b3c97a0beae527502dc1164159812024-02-20 12:05:395 days 10 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0xc96071d9168a68e26a756ddecf9477d5b620212f44d90b3c97a0beae527502dc1164159812024-02-20 12:05:395 days 10 hrs ago 0x87cdbbcb50feeef407b083659ab74b0547788c59 Synthetix: Perps V2 Proxy XRPPERP1 wei
0x2dcf40b49f4bd5147f86ffae8521a9d65ff1f2dee90940fbaf0c90be654696fa1164159812024-02-20 12:05:395 days 10 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0xf14ecc577c75468b981a2d8dad599e54f2cc6a5666072014f968f250d92053621161022002024-02-13 5:46:1712 days 16 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0xf14ecc577c75468b981a2d8dad599e54f2cc6a5666072014f968f250d92053621161022002024-02-13 5:46:1712 days 16 hrs ago 0x30609910c6fbff5bb7afa0732ccfefa6419654f1 Synthetix: Perps V2 Proxy XRPPERP1 wei
0x747a94b28dcfa63a1f0804f218eb94f4837ee17ebe86fe3606422005189280ab1157714772024-02-05 14:02:1120 days 8 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0x747a94b28dcfa63a1f0804f218eb94f4837ee17ebe86fe3606422005189280ab1157714772024-02-05 14:02:1120 days 8 hrs ago 0x87cdbbcb50feeef407b083659ab74b0547788c59 Synthetix: Perps V2 Proxy XRPPERP1 wei
0xfa9ecae4ea10c4d38c82ce611e3c27b5a102d98610b87c179eb6e2275dfcbe581152164512024-01-23 17:41:1933 days 5 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0xfa9ecae4ea10c4d38c82ce611e3c27b5a102d98610b87c179eb6e2275dfcbe581152164512024-01-23 17:41:1933 days 5 hrs ago 0x87cdbbcb50feeef407b083659ab74b0547788c59 Synthetix: Perps V2 Proxy XRPPERP1 wei
0x1185d502fd938e840af7677f3d34886495a807716ac37a4a79288d503309211a1152001392024-01-23 8:37:3533 days 14 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0x1185d502fd938e840af7677f3d34886495a807716ac37a4a79288d503309211a1152001392024-01-23 8:37:3533 days 14 hrs ago 0x87cdbbcb50feeef407b083659ab74b0547788c59 Synthetix: Perps V2 Proxy XRPPERP1 wei
0x67772d15222ae6b1d9a00979ee819bcff14697e579662774d98d023d913d9ad51151493732024-01-22 4:25:2334 days 18 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0x67772d15222ae6b1d9a00979ee819bcff14697e579662774d98d023d913d9ad51151493732024-01-22 4:25:2334 days 18 hrs ago 0x87cdbbcb50feeef407b083659ab74b0547788c59 Synthetix: Perps V2 Proxy XRPPERP1 wei
0xe6a6e54fce5b863eb78ed7a1a598246ec8efc7adefa9a6d72f07e34eb5d5267d1150027322024-01-18 18:57:2138 days 3 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0xe6a6e54fce5b863eb78ed7a1a598246ec8efc7adefa9a6d72f07e34eb5d5267d1150027322024-01-18 18:57:2138 days 3 hrs ago 0x30609910c6fbff5bb7afa0732ccfefa6419654f1 Synthetix: Perps V2 Proxy XRPPERP1 wei
0x0900276e4d8a1fc2f7ba4a73c2af3066a25520d6e19aa642367e538be503db241149995672024-01-18 17:11:5138 days 5 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0x0900276e4d8a1fc2f7ba4a73c2af3066a25520d6e19aa642367e538be503db241149995672024-01-18 17:11:5138 days 5 hrs ago 0x87cdbbcb50feeef407b083659ab74b0547788c59 Synthetix: Perps V2 Proxy XRPPERP1 wei
0x1daf375b3c6f31253ae8386c08e503092b45dfab38e4c20111d27b1c7133139e1149724702024-01-18 2:08:3738 days 20 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
0x1daf375b3c6f31253ae8386c08e503092b45dfab38e4c20111d27b1c7133139e1149724702024-01-18 2:08:3738 days 20 hrs ago 0x30609910c6fbff5bb7afa0732ccfefa6419654f1 Synthetix: Perps V2 Proxy XRPPERP1 wei
0x74f7d2bf3eae61a05b18762a14f13cdf12fa72186dacccdee98aa6a32ffa31c31149724702024-01-18 2:08:3738 days 20 hrs ago Synthetix: Perps V2 Proxy XRPPERP Synthetix: Perps V2 Delayed Execution XAUPERP1 wei
[ Download CSV Export 
Loading

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

Contract Name:
ProxyPerpsV2

Compiler Version
v0.5.16+commit.9c3226ce

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
/**
 *Submitted for verification at Optimistic.Etherscan.io on 2023-02-07
*/

/*
   ____            __   __        __   _
  / __/__ __ ___  / /_ / /  ___  / /_ (_)__ __
 _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ /
/___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\
     /___/

* Synthetix: ProxyPerpsV2.sol
*
* Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/ProxyPerpsV2.sol
* Docs: https://docs.synthetix.io/contracts/ProxyPerpsV2
*
* Contract Dependencies: 
*	- Owned
* Libraries: (none)
*
* MIT License
* ===========
*
* Copyright (c) 2023 Synthetix
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*/



pragma solidity ^0.5.16;

// https://docs.synthetix.io/contracts/source/contracts/owned
contract Owned {
    address public owner;
    address public nominatedOwner;

    constructor(address _owner) public {
        require(_owner != address(0), "Owner address cannot be 0");
        owner = _owner;
        emit OwnerChanged(address(0), _owner);
    }

    function nominateNewOwner(address _owner) external onlyOwner {
        nominatedOwner = _owner;
        emit OwnerNominated(_owner);
    }

    function acceptOwnership() external {
        require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
        emit OwnerChanged(owner, nominatedOwner);
        owner = nominatedOwner;
        nominatedOwner = address(0);
    }

    modifier onlyOwner {
        _onlyOwner();
        _;
    }

    function _onlyOwner() private view {
        require(msg.sender == owner, "Only the contract owner may perform this action");
    }

    event OwnerNominated(address newOwner);
    event OwnerChanged(address oldOwner, address newOwner);
}


// Inheritance


// Internal references


// https://docs.synthetix.io/contracts/source/contracts/proxy
contract Proxy is Owned {
    Proxyable public target;

    constructor(address _owner) public Owned(_owner) {}

    function setTarget(Proxyable _target) external onlyOwner {
        target = _target;
        emit TargetUpdated(_target);
    }

    function _emit(
        bytes calldata callData,
        uint numTopics,
        bytes32 topic1,
        bytes32 topic2,
        bytes32 topic3,
        bytes32 topic4
    ) external onlyTarget {
        uint size = callData.length;
        bytes memory _callData = callData;

        assembly {
            /* The first 32 bytes of callData contain its length (as specified by the abi).
             * Length is assumed to be a uint256 and therefore maximum of 32 bytes
             * in length. It is also leftpadded to be a multiple of 32 bytes.
             * This means moving call_data across 32 bytes guarantees we correctly access
             * the data itself. */
            switch numTopics
                case 0 {
                    log0(add(_callData, 32), size)
                }
                case 1 {
                    log1(add(_callData, 32), size, topic1)
                }
                case 2 {
                    log2(add(_callData, 32), size, topic1, topic2)
                }
                case 3 {
                    log3(add(_callData, 32), size, topic1, topic2, topic3)
                }
                case 4 {
                    log4(add(_callData, 32), size, topic1, topic2, topic3, topic4)
                }
        }
    }

    // solhint-disable no-complex-fallback
    function() external payable {
        // Mutable call setting Proxyable.messageSender as this is using call not delegatecall
        target.setMessageSender(msg.sender);

        assembly {
            let free_ptr := mload(0x40)
            calldatacopy(free_ptr, 0, calldatasize)

            /* We must explicitly forward ether to the underlying contract as well. */
            let result := call(gas, sload(target_slot), callvalue, free_ptr, calldatasize, 0, 0)
            returndatacopy(free_ptr, 0, returndatasize)

            if iszero(result) {
                revert(free_ptr, returndatasize)
            }
            return(free_ptr, returndatasize)
        }
    }

    modifier onlyTarget {
        require(Proxyable(msg.sender) == target, "Must be proxy target");
        _;
    }

    event TargetUpdated(Proxyable newTarget);
}


// Inheritance


// Internal references


// https://docs.synthetix.io/contracts/source/contracts/proxyable
contract Proxyable is Owned {
    // This contract should be treated like an abstract contract

    /* The proxy this contract exists behind. */
    Proxy public proxy;

    /* The caller of the proxy, passed through to this contract.
     * Note that every function using this member must apply the onlyProxy or
     * optionalProxy modifiers, otherwise their invocations can use stale values. */
    address public messageSender;

    constructor(address payable _proxy) internal {
        // This contract is abstract, and thus cannot be instantiated directly
        require(owner != address(0), "Owner must be set");

        proxy = Proxy(_proxy);
        emit ProxyUpdated(_proxy);
    }

    function setProxy(address payable _proxy) external onlyOwner {
        proxy = Proxy(_proxy);
        emit ProxyUpdated(_proxy);
    }

    function setMessageSender(address sender) external onlyProxy {
        messageSender = sender;
    }

    modifier onlyProxy {
        _onlyProxy();
        _;
    }

    function _onlyProxy() private view {
        require(Proxy(msg.sender) == proxy, "Only the proxy can call");
    }

    modifier optionalProxy {
        _optionalProxy();
        _;
    }

    function _optionalProxy() private {
        if (Proxy(msg.sender) != proxy && messageSender != msg.sender) {
            messageSender = msg.sender;
        }
    }

    modifier optionalProxy_onlyOwner {
        _optionalProxy_onlyOwner();
        _;
    }

    // solhint-disable-next-line func-name-mixedcase
    function _optionalProxy_onlyOwner() private {
        if (Proxy(msg.sender) != proxy && messageSender != msg.sender) {
            messageSender = msg.sender;
        }
        require(messageSender == owner, "Owner only function");
    }

    event ProxyUpdated(address proxyAddress);
}


pragma experimental ABIEncoderV2;

// Inheritance


// Internal references


/**
 * Based on Proxy.sol that adds routing capabilities to route specific function calls (selectors) to
 * specific implementations and flagging the routes if are views in order to not call
 * proxyable.setMessageSender() that is mutative (resulting in a revert).
 *
 * In order to manage the routes it provides two onlyOwner functions (`addRoute` and `removeRoute`), and
 * some helper views to get the size of the route list (`getRoutesLength`), the list of routes (`getRoutesPage`),
 * and a list of all the targeted contracts.
 */
// https://docs.synthetix.io/contracts/source/contracts/ProxyPerpsV2
contract ProxyPerpsV2 is Owned {
    /* ----- Dynamic router storage ----- */
    struct Route {
        bytes4 selector;
        address implementation;
        bool isView;
    }

    // Route definition and index to quickly access it
    Route[] internal _routes;
    mapping(bytes4 => uint) internal _routeIndexes;
    // number of routes referencing a target, if number is greater than zero, it means the address is a valid target
    mapping(address => uint) internal _targetReferences;
    // list of valid target addresses (more than zero references in the routes)
    address[] internal _routedTargets;

    constructor(address _owner) public Owned(_owner) {}

    /* ----- Dynamic router administration ----- */
    function _contains(bytes4 selector) internal view returns (bool) {
        if (_routes.length == 0) {
            return false;
        }
        uint index = _routeIndexes[selector];
        return index != 0 || _routes[0].selector == selector;
    }

    function _removeTargetReference(address implementation) internal {
        require(_targetReferences[implementation] > 0, "Target not referenced.");

        // Decrement the references
        _targetReferences[implementation] -= 1;

        // if was the latest reference, remove it from the _routedTargets and emit an event
        if (_targetReferences[implementation] == 0) {
            // Accepting a for loop since implementations for a market is going to be a very limited number (initially only 2)
            for (uint idx = 0; idx < _routedTargets.length; idx++) {
                if (_routedTargets[idx] == implementation) {
                    // remove it by bringing the last one to that position and poping the latest item (if it's the latest one will do an unecessary write)
                    _routedTargets[idx] = _routedTargets[_routedTargets.length - 1];
                    _routedTargets.pop();
                    break;
                }
            }

            emit TargetedRouteRemoved(implementation);
        }
    }

    function addRoute(
        bytes4 selector,
        address implementation,
        bool isView
    ) external onlyOwner {
        require(selector != bytes4(0), "Invalid nil selector");

        if (_contains(selector)) {
            // Update data
            Route storage route = _routes[_routeIndexes[selector]];

            // Remove old implementation reference
            _removeTargetReference(route.implementation);

            route.selector = selector;
            route.implementation = implementation;
            route.isView = isView;
        } else {
            // Add data
            _routeIndexes[selector] = _routes.length;
            Route memory newRoute;
            newRoute.selector = selector;
            newRoute.implementation = implementation;
            newRoute.isView = isView;

            _routes.push(newRoute);
        }

        // Add to targeted references
        _targetReferences[implementation] += 1;
        if (_targetReferences[implementation] == 1) {
            // First reference, add to routed targets and emit the event
            _routedTargets.push(implementation);
            emit TargetedRouteAdded(implementation);
        }

        emit RouteUpdated(selector, implementation, isView);
    }

    function removeRoute(bytes4 selector) external onlyOwner {
        require(_contains(selector), "Selector not in set.");

        // Replace the removed selector with the last selector of the list.
        uint index = _routeIndexes[selector];
        uint lastIndex = _routes.length - 1; // We required that selector is in the list, so it is not empty.

        // Remove target reference
        _removeTargetReference(_routes[index].implementation);

        // Ensure target is in latest index
        if (index != lastIndex) {
            // No need to shift the last selector if it is the one we want to delete.
            Route storage shiftedElement = _routes[lastIndex];
            _routes[index] = shiftedElement;
            _routeIndexes[shiftedElement.selector] = index;
        }

        // Remove target
        _routes.pop();
        delete _routeIndexes[selector];
        emit RouteRemoved(selector);
    }

    function getRoute(bytes4 selector) external view returns (Route memory) {
        if (!_contains(selector)) {
            return Route(0, address(0), false);
        }
        return _routes[_routeIndexes[selector]];
    }

    function getRoutesLength() external view returns (uint) {
        return _routes.length;
    }

    function getRoutesPage(uint index, uint pageSize) external view returns (Route[] memory) {
        // NOTE: This implementation should be converted to slice operators if the compiler is updated to v0.6.0+
        uint endIndex = index + pageSize; // The check below that endIndex <= index handles overflow.

        // If the page extends past the end of the list, truncate it.
        if (endIndex > _routes.length) {
            endIndex = _routes.length;
        }
        if (endIndex <= index) {
            return new Route[](0);
        }

        uint n = endIndex - index; // We already checked for negative overflow.
        Route[] memory page = new Route[](n);
        for (uint i; i < n; i++) {
            page[i] = _routes[i + index];
        }
        return page;
    }

    function getAllTargets() external view returns (address[] memory) {
        return _routedTargets;
    }

    ///// BASED ON PROXY.SOL /////
    /* ----- Proxy based on Proxy.sol ----- */

    function _emit(
        bytes calldata callData,
        uint numTopics,
        bytes32 topic1,
        bytes32 topic2,
        bytes32 topic3,
        bytes32 topic4
    ) external onlyTargets {
        uint size = callData.length;
        bytes memory _callData = callData;

        assembly {
            /* The first 32 bytes of callData contain its length (as specified by the abi).
             * Length is assumed to be a uint256 and therefore maximum of 32 bytes
             * in length. It is also leftpadded to be a multiple of 32 bytes.
             * This means moving call_data across 32 bytes guarantees we correctly access
             * the data itself. */
            switch numTopics
                case 0 {
                    log0(add(_callData, 32), size)
                }
                case 1 {
                    log1(add(_callData, 32), size, topic1)
                }
                case 2 {
                    log2(add(_callData, 32), size, topic1, topic2)
                }
                case 3 {
                    log3(add(_callData, 32), size, topic1, topic2, topic3)
                }
                case 4 {
                    log4(add(_callData, 32), size, topic1, topic2, topic3, topic4)
                }
        }
    }

    // solhint-disable no-complex-fallback
    function() external payable {
        bytes4 sig4 = msg.sig;

        require(_contains(sig4), "Invalid selector");

        // Identify target
        address implementation = _routes[_routeIndexes[sig4]].implementation;
        bool isView = _routes[_routeIndexes[sig4]].isView;

        if (isView) {
            assembly {
                let free_ptr := mload(0x40)
                calldatacopy(free_ptr, 0, calldatasize)

                /* We must explicitly forward ether to the underlying contract as well. */
                let result := staticcall(gas, implementation, free_ptr, calldatasize, 0, 0)
                returndatacopy(free_ptr, 0, returndatasize)

                if iszero(result) {
                    revert(free_ptr, returndatasize)
                }
                return(free_ptr, returndatasize)
            }
        } else {
            // Mutable call setting Proxyable.messageSender as this is using call not delegatecall
            Proxyable(implementation).setMessageSender(msg.sender);
            assembly {
                let free_ptr := mload(0x40)
                calldatacopy(free_ptr, 0, calldatasize)

                /* We must explicitly forward ether to the underlying contract as well. */
                let result := call(gas, implementation, callvalue, free_ptr, calldatasize, 0, 0)
                returndatacopy(free_ptr, 0, returndatasize)

                if iszero(result) {
                    revert(free_ptr, returndatasize)
                }
                return(free_ptr, returndatasize)
            }
        }
    }

    modifier onlyTargets {
        require(_targetReferences[msg.sender] > 0, "Must be a proxy target");
        _;
    }

    event RouteUpdated(bytes4 route, address implementation, bool isView);

    event RouteRemoved(bytes4 route);

    event TargetedRouteAdded(address targetedRoute);

    event TargetedRouteRemoved(address targetedRoute);
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes4","name":"route","type":"bytes4"}],"name":"RouteRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes4","name":"route","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementation","type":"address"},{"indexed":false,"internalType":"bool","name":"isView","type":"bool"}],"name":"RouteUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"targetedRoute","type":"address"}],"name":"TargetedRouteAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"targetedRoute","type":"address"}],"name":"TargetedRouteRemoved","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"numTopics","type":"uint256"},{"internalType":"bytes32","name":"topic1","type":"bytes32"},{"internalType":"bytes32","name":"topic2","type":"bytes32"},{"internalType":"bytes32","name":"topic3","type":"bytes32"},{"internalType":"bytes32","name":"topic4","type":"bytes32"}],"name":"_emit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"},{"internalType":"address","name":"implementation","type":"address"},{"internalType":"bool","name":"isView","type":"bool"}],"name":"addRoute","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAllTargets","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"getRoute","outputs":[{"components":[{"internalType":"bytes4","name":"selector","type":"bytes4"},{"internalType":"address","name":"implementation","type":"address"},{"internalType":"bool","name":"isView","type":"bool"}],"internalType":"struct ProxyPerpsV2.Route","name":"","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRoutesLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"getRoutesPage","outputs":[{"components":[{"internalType":"bytes4","name":"selector","type":"bytes4"},{"internalType":"address","name":"implementation","type":"address"},{"internalType":"bool","name":"isView","type":"bool"}],"internalType":"struct ProxyPerpsV2.Route[]","name":"","type":"tuple[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"removeRoute","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

Deployed Bytecode

0x60806040526004361061009c5760003560e01c806345019a971161006457806345019a97146102bd57806353a47bb7146102ea5780637696b5bb1461030c57806379ba50971461032e5780638da5cb5b14610343578063907dff97146103585761009c565b80631627540c146102035780631939f17f146102255780631a6e649e146102455780631d46021f1461027b5780633a671e641461029d575b6001600160e01b0319600035166100b281610378565b6100d75760405162461bcd60e51b81526004016100ce906113d0565b60405180910390fd5b6001600160e01b0319811660009081526003602052604081205460028054909190811061010057fe5b6000918252602080832091909101546001600160e01b0319851683526003909152604082205460028054600160201b9093046001600160a01b0316945091811061014657fe5b600091825260209091200154600160c01b900460ff16905080156101865760405136600082376000803683865afa3d6000833e80610182573d82fd5b3d82f35b604051635e33fc1960e11b81526001600160a01b0383169063bc67f832906101b2903390600401611308565b600060405180830381600087803b1580156101cc57600080fd5b505af11580156101e0573d6000803e3d6000fd5b505050506040513660008237600080368334875af13d6000833e80610182573d82fd5b34801561020f57600080fd5b5061022361021e366004610eb4565b6103ea565b005b34801561023157600080fd5b50610223610240366004610ef8565b610448565b34801561025157600080fd5b50610265610260366004610eda565b6106d9565b6040516102729190611400565b60405180910390f35b34801561028757600080fd5b50610290610796565b6040516102729190611338565b3480156102a957600080fd5b506102236102b8366004610eda565b6107f8565b3480156102c957600080fd5b506102dd6102d8366004610fe9565b6109b1565b6040516102729190611349565b3480156102f657600080fd5b506102ff610ae7565b60405161027291906112fa565b34801561031857600080fd5b50610321610af6565b604051610272919061140e565b34801561033a57600080fd5b50610223610afc565b34801561034f57600080fd5b506102ff610b98565b34801561036457600080fd5b50610223610373366004610f45565b610ba7565b60025460009061038a575060006103e5565b6001600160e01b03198216600090815260036020526040902054801515806103e15750826001600160e01b03191660026000815481106103c657fe5b60009182526020909120015460e01b6001600160e01b031916145b9150505b919050565b6103f2610c86565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229061043d9083906112fa565b60405180910390a150565b610450610c86565b6001600160e01b031983166104775760405162461bcd60e51b81526004016100ce906113b0565b61048083610378565b1561051d576001600160e01b031983166000908152600360205260408120546002805490919081106104ae57fe5b600091825260209091200180549091506104d790600160201b90046001600160a01b0316610cb2565b805463ffffffff191660e085901c17640100000000600160c01b031916600160201b6001600160a01b038516021760ff60c01b1916600160c01b831515021790556105ec565b6002546001600160e01b03198416600090815260036020526040902055610542610e1f565b6001600160e01b0319841681526001600160a01b0380841660208301908152831515604084019081526002805460018101825560009190915293517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace9094018054925191511515600160c01b0260ff60c01b1992909416600160201b02640100000000600160c01b031960e09690961c63ffffffff19909416939093179490941691909117161790555b6001600160a01b03821660009081526004602052604090208054600190810191829055141561069957600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319166001600160a01b0384161790556040517f754dc0878f0e981d97e717f071376c2d2fe16d7f004be06dbadb70b6947075ab906106909084906112fa565b60405180910390a15b7f50baa98668b326aa278119ffadc1468a16913ac8582b3cbd063c7e69e4b2bdd08383836040516106cc93929190611368565b60405180910390a1505050565b6106e1610e1f565b6106ea82610378565b610711575060408051606081018252600080825260208201819052918101919091526103e5565b6001600160e01b0319821660009081526003602052604090205460028054909190811061073a57fe5b600091825260209182902060408051606081018252929091015460e081901b6001600160e01b0319168352600160201b81046001600160a01b031693830193909352600160c01b90920460ff1615159181019190915292915050565b606060058054806020026020016040519081016040528092919081815260200182805480156107ee57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116107d0575b5050505050905090565b610800610c86565b61080981610378565b6108255760405162461bcd60e51b81526004016100ce906113a0565b6001600160e01b0319811660009081526003602052604090205460028054600019810191610878918490811061085757fe5b600091825260209091200154600160201b90046001600160a01b0316610cb2565b8082146109385760006002828154811061088e57fe5b90600052602060002001905080600284815481106108a857fe5b6000918252602080832084549201805463ffffffff191663ffffffff909316929092178083558454640100000000600160c01b0319909116600160201b918290046001600160a01b031690910217808355935460ff60c01b19909416600160c01b9485900460ff161515909402939093179055915460e01b6001600160e01b031916825260039052604090208290555b600280548061094357fe5b60008281526020808220830160001990810180546001600160c81b03191690559092019092556001600160e01b03198516825260039052604080822091909155517f76d504ba17812cd58154028a97a1e6704678fd628c01ae5514483383a787e959906106cc90859061135a565b600254606090838301908111156109c757506002545b838111610a085760408051600080825260208201909252906109ff565b6109ec610e1f565b8152602001906001900390816109e45790505b50915050610ae1565b604080518583038082526020808202830101909252606090828015610a4757816020015b610a34610e1f565b815260200190600190039081610a2c5790505b50905060005b82811015610adb57600287820181548110610a6457fe5b60009182526020918290206040805160608101825291909201546001600160e01b031960e082901b1682526001600160a01b03600160201b8204169382019390935260ff600160c01b909304929092161515908201528251839083908110610ac857fe5b6020908102919091010152600101610a4d565b50925050505b92915050565b6001546001600160a01b031681565b60025490565b6001546001600160a01b03163314610b265760405162461bcd60e51b81526004016100ce90611390565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c92610b69926001600160a01b0391821692911690611316565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6000546001600160a01b031681565b33600090815260046020526040902054610bd35760405162461bcd60e51b81526004016100ce906113c0565b604080516020601f89018190048102820181019092528781528791606091908a908490819084018382808284376000920191909152509293508992505081159050610c3d5760018114610c485760028114610c545760038114610c615760048114610c6f57610c7a565b8260208301a0610c7a565b868360208401a1610c7a565b85878460208501a2610c7a565b8486888560208601a3610c7a565b838587898660208701a45b50505050505050505050565b6000546001600160a01b03163314610cb05760405162461bcd60e51b81526004016100ce906113e0565b565b6001600160a01b038116600090815260046020526040902054610ce75760405162461bcd60e51b81526004016100ce906113f0565b6001600160a01b038116600090815260046020526040902080546000190190819055610e1c5760005b600554811015610dec57816001600160a01b031660058281548110610d3157fe5b6000918252602090912001546001600160a01b03161415610de457600580546000198101908110610d5e57fe5b600091825260209091200154600580546001600160a01b039092169183908110610d8457fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506005805480610dbd57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055610dec565b600101610d10565b507fc46f5d4a0bdb1a319220635019815a6b89dbb2edf2a73b6ac3259edd2405b8088160405161043d91906112fa565b50565b604080516060810182526000808252602082018190529181019190915290565b8035610ae18161146c565b8035610ae181611480565b8035610ae181611489565b8035610ae181611492565b60008083601f840112610e7d57600080fd5b50813567ffffffffffffffff811115610e9557600080fd5b602083019150836001820283011115610ead57600080fd5b9250929050565b600060208284031215610ec657600080fd5b6000610ed28484610e3f565b949350505050565b600060208284031215610eec57600080fd5b6000610ed28484610e60565b600080600060608486031215610f0d57600080fd5b6000610f198686610e60565b9350506020610f2a86828701610e3f565b9250506040610f3b86828701610e4a565b9150509250925092565b600080600080600080600060c0888a031215610f6057600080fd5b873567ffffffffffffffff811115610f7757600080fd5b610f838a828b01610e6b565b97509750506020610f968a828b01610e55565b9550506040610fa78a828b01610e55565b9450506060610fb88a828b01610e55565b9350506080610fc98a828b01610e55565b92505060a0610fda8a828b01610e55565b91505092959891949750929550565b60008060408385031215610ffc57600080fd5b60006110088585610e55565b925050602061101985828601610e55565b9150509250929050565b600061102f838361105a565b505060200190565b600061104383836112b4565b505060600190565b6110548161145b565b82525050565b6110548161142f565b600061106e82611422565b6110788185611426565b93506110838361141c565b8060005b838110156110b157815161109b8882611023565b97506110a68361141c565b925050600101611087565b509495945050505050565b60006110c782611422565b6110d18185611426565b93506110dc8361141c565b8060005b838110156110b15781516110f48882611037565b97506110ff8361141c565b9250506001016110e0565b6110548161143a565b61105481611442565b6000611129603583611426565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b6000611180601483611426565b7329b2b632b1ba37b9103737ba1034b71039b2ba1760611b815260200192915050565b60006111b0601483611426565b7324b73b30b634b2103734b61039b2b632b1ba37b960611b815260200192915050565b60006111e0601683611426565b75135d5cdd0818994818481c1c9bde1e481d185c99d95d60521b815260200192915050565b6000611212601083611426565b6f24b73b30b634b21039b2b632b1ba37b960811b815260200192915050565b600061123e602f83611426565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b600061128f601683611426565b752a30b933b2ba103737ba103932b332b932b731b2b21760511b815260200192915050565b805160608301906112c58482611113565b5060208201516112d8602085018261105a565b5060408201516112eb604085018261110a565b50505050565b6110548161143f565b60208101610ae1828461105a565b60208101610ae1828461104b565b60408101611324828561105a565b611331602083018461105a565b9392505050565b602080825281016113318184611063565b6020808252810161133181846110bc565b60208101610ae18284611113565b606081016113768286611113565b611383602083018561105a565b610ed2604083018461110a565b60208082528101610ae18161111c565b60208082528101610ae181611173565b60208082528101610ae1816111a3565b60208082528101610ae1816111d3565b60208082528101610ae181611205565b60208082528101610ae181611231565b60208082528101610ae181611282565b60608101610ae182846112b4565b60208101610ae182846112f1565b60200190565b5190565b90815260200190565b6000610ae18261144f565b151590565b90565b6001600160e01b03191690565b6001600160a01b031690565b6000610ae1826000610ae18261142f565b6114758161142f565b8114610e1c57600080fd5b6114758161143a565b6114758161143f565b6114758161144256fea365627a7a7231582027a6d101e30d92532035de6f77e97413176e0fad77c85f79471acae70e202da96c6578706572696d656e74616cf564736f6c63430005100040

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