false
true
0

Contract Address Details

0x87698dC376315b5cef57fe015a9a34A622fa8051

Contract Name
Delegator
Creator
0xb94333–acb7c0 at 0xb7bfc5–b767b9
Balance
0 tPLS
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
25428436
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
Delegator




Optimization enabled
true
Compiler version
v0.8.17+commit.8df45f5f




Optimization runs
200
EVM Version
default




Verified at
2025-04-30T20:24:52.302336Z

Constructor Arguments

0x000000000000000000000000b94333ca4de54f79b24294582471c9c336acb7c0

Arg [0] (address) : 0xb94333ca4de54f79b24294582471c9c336acb7c0

              

contracts/governance/Delegator.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.7;
pragma abicoder v2;

// OpenZeppelin v4
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title Delegator
 * @author Railgun Contributors
 * @notice 'Owner' contract for all railgun contracts
 * delegates permissions to other contracts (voter, role)
 */
contract Delegator is Ownable {
  /*
  Mapping structure is calling address => contract => function signature
  0 is used as a wildcard, so permission for contract 0 is permission for
  any contract, and permission for function signature 0 is permission for
  any function.

  Comments below use * to signify wildcard and . notation to separate address/contract/function.

  caller.*.* allows caller to call any function on any contract
  caller.X.* allows caller to call any function on contract X
  caller.*.Y allows caller to call function Y on any contract
  */
  mapping(address => mapping(address => mapping(bytes4 => bool))) public permissions;

  event GrantPermission(
    address indexed caller,
    address indexed contractAddress,
    bytes4 indexed selector
  );
  event RevokePermission(
    address indexed caller,
    address indexed contractAddress,
    bytes4 indexed selector
  );

  /**
   * @notice Sets initial admin
   */
  constructor(address _admin) {
    Ownable.transferOwnership(_admin);
  }

  /**
   * @notice Sets permission bit
   * @dev See comment on permissions mapping for wildcard format
   * @param _caller - caller to set permissions for
   * @param _contract - contract to set permissions for
   * @param _selector - selector to set permissions for
   * @param _permission - permission bit to set
   */
  function setPermission(
    address _caller,
    address _contract,
    bytes4 _selector,
    bool _permission
  ) public onlyOwner {
    // If permission set is different to new permission then we execute, otherwise skip
    if (permissions[_caller][_contract][_selector] != _permission) {
      // Set permission bit
      permissions[_caller][_contract][_selector] = _permission;

      // Emit event
      if (_permission) {
        emit GrantPermission(_caller, _contract, _selector);
      } else {
        emit RevokePermission(_caller, _contract, _selector);
      }
    }
  }

  /**
   * @notice Checks if caller has permission to execute function
   * @param _caller - caller to check permissions for
   * @param _contract - contract to check
   * @param _selector - function signature to check
   * @return if caller has permission
   */
  function checkPermission(
    address _caller,
    address _contract,
    bytes4 _selector
  ) public view returns (bool) {
    /* 
    See comment on permissions mapping for structure
    Comments below use * to signify wildcard and . notation to separate contract/function
    */
    return (_caller == Ownable.owner() ||
      permissions[_caller][_contract][_selector] || // Owner always has global permissions
      permissions[_caller][_contract][0x0] || // Permission for function is given
      permissions[_caller][address(0)][_selector] || // Permission for _contract.* is given
      permissions[_caller][address(0)][0x0]); // Global permission is given
  }

  /**
   * @notice Calls function
   * @dev calls to functions on this contract are intercepted and run directly
   * this is so the voting contract doesn't need to have special cases for calling
   * functions other than this one.
   * @param _contract - contract to call
   * @param _data - calldata to pass to contract
   * @return success - whether call succeeded
   * @return returnData - return data from function call
   */
  function callContract(
    address _contract,
    bytes calldata _data,
    uint256 _value
  ) public returns (bool success, bytes memory returnData) {
    // Get selector
    bytes4 selector = bytes4(_data);

    // Intercept calls to this contract
    if (_contract == address(this)) {
      if (selector == this.setPermission.selector) {
        // Decode call data
        (address caller, address calledContract, bytes4 _permissionSelector, bool permission) = abi
          .decode(abi.encodePacked(_data[4:]), (address, address, bytes4, bool));

        // Call setPermission
        setPermission(caller, calledContract, _permissionSelector, permission);

        // Return success with empty ReturnData bytes
        bytes memory empty;
        return (true, empty);
      } else if (selector == this.transferOwnership.selector) {
        // Decode call data
        address newOwner = abi.decode(abi.encodePacked(_data[4:]), (address));

        // Call transferOwnership
        Ownable.transferOwnership(newOwner);

        // Return success with empty ReturnData bytes
        bytes memory empty;
        return (true, empty);
      } else if (selector == this.renounceOwnership.selector) {
        // Call renounceOwnership
        Ownable.renounceOwnership();

        // Return success with empty ReturnData bytes
        bytes memory empty;
        return (true, empty);
      } else {
        // Return failed with empty ReturnData bytes
        bytes memory empty;
        return (false, empty);
      }
    }

    // Check permissions
    require(
      checkPermission(msg.sender, _contract, selector),
      "Delegator: Caller doesn't have permission"
    );

    // Call external contract and return
    // solhint-disable-next-line avoid-low-level-calls
    return _contract.call{ value: _value }(_data);
  }
}
        

@openzeppelin/contracts/access/Ownable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

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() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(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");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
          

@openzeppelin/contracts/utils/Context.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}
          

Compiler Settings

{"outputSelection":{"*":{"*":["storageLayout","abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"],"":["ast"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_admin","internalType":"address"}]},{"type":"event","name":"GrantPermission","inputs":[{"type":"address","name":"caller","internalType":"address","indexed":true},{"type":"address","name":"contractAddress","internalType":"address","indexed":true},{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RevokePermission","inputs":[{"type":"address","name":"caller","internalType":"address","indexed":true},{"type":"address","name":"contractAddress","internalType":"address","indexed":true},{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"},{"type":"bytes","name":"returnData","internalType":"bytes"}],"name":"callContract","inputs":[{"type":"address","name":"_contract","internalType":"address"},{"type":"bytes","name":"_data","internalType":"bytes"},{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"checkPermission","inputs":[{"type":"address","name":"_caller","internalType":"address"},{"type":"address","name":"_contract","internalType":"address"},{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"permissions","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"},{"type":"bytes4","name":"","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPermission","inputs":[{"type":"address","name":"_caller","internalType":"address"},{"type":"address","name":"_contract","internalType":"address"},{"type":"bytes4","name":"_selector","internalType":"bytes4"},{"type":"bool","name":"_permission","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
              

Contract Creation Code

0x608060405234801561001057600080fd5b50604051610ba6380380610ba683398101604081905261002f9161017b565b61003833610051565b61004b816100a160201b6105d11760201c565b506101ab565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6100a961011f565b6001600160a01b0381166101135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61011c81610051565b50565b6000546001600160a01b031633146101795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161010a565b565b60006020828403121561018d57600080fd5b81516001600160a01b03811681146101a457600080fd5b9392505050565b6109ec806101ba6000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100e8578063c6b295c114610103578063e64624fa14610124578063f2fde38b1461013757600080fd5b8063715018a6146100825780637aa7d3fd1461008c5780638ad2f289146100d5575b600080fd5b61008a61014a565b005b6100c061009a36600461071f565b600160209081526000938452604080852082529284528284209052825290205460ff1681565b60405190151581526020015b60405180910390f35b6100c06100e336600461071f565b61015e565b6000546040516001600160a01b0390911681526020016100cc565b61011661011136600461076a565b610265565b6040516100cc9291906107f5565b61008a61013236600461085b565b610496565b61008a6101453660046108b7565b6105d1565b61015261064a565b61015c60006106a4565b565b600080546001600160a01b03858116911614806101b257506001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff165b806101ea57506001600160a01b03808516600090815260016020908152604080832093871683529281528282208280529052205460ff165b8061022a57506001600160a01b038416600090815260016020908152604080832083805282528083206001600160e01b03198616845290915290205460ff165b8061025d57506001600160a01b0384166000908152600160209081526040808320838052825280832090915290205460ff165b949350505050565b600060608161027485876108db565b9050306001600160a01b038816036103bb57630cdced8360e11b6001600160e01b031982160161030a5760008080806102b0896004818d61090b565b6040516020016102c1929190610935565b6040516020818303038152906040528060200190518101906102e39190610945565b93509350935093506102f784848484610496565b50600195506060945061048d9350505050565b630d021c7560e01b6001600160e01b031982160161037f576000610331866004818a61090b565b604051602001610342929190610935565b6040516020818303038152906040528060200190518101906103649190610999565b905061036f816105d1565b50600192506060915061048d9050565b634757f3ad60e11b6001600160e01b03198216016103ad5761039f61014a565b50600191506060905061048d565b50600091506060905061048d565b6103c633888361015e565b6104295760405162461bcd60e51b815260206004820152602960248201527f44656c656761746f723a2043616c6c657220646f65736e27742068617665207060448201526832b936b4b9b9b4b7b760b91b60648201526084015b60405180910390fd5b866001600160a01b0316848787604051610444929190610935565b60006040518083038185875af1925050503d8060008114610481576040519150601f19603f3d011682016040523d82523d6000602084013e610486565b606091505b5092509250505b94509492505050565b61049e61064a565b6001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff161515811515146105cb576001600160a01b03848116600090815260016020908152604080832093871683529281528282206001600160e01b031986168352905220805460ff1916821580159190911790915561057f57816001600160e01b031916836001600160a01b0316856001600160a01b03167f521b363b3401f4d6404e4bd855a3edf8d254a7f55abb97b6d516b66a6f86205e60405160405180910390a46105cb565b816001600160e01b031916836001600160a01b0316856001600160a01b03167f91f81f13bab4e6573f47dda4f090782eb2c9173d3d489ca191b5f4f7355cebe860405160405180910390a45b50505050565b6105d961064a565b6001600160a01b03811661063e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610420565b610647816106a4565b50565b6000546001600160a01b0316331461015c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610420565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461064757600080fd5b6001600160e01b03198116811461064757600080fd5b60008060006060848603121561073457600080fd5b833561073f816106f4565b9250602084013561074f816106f4565b9150604084013561075f81610709565b809150509250925092565b6000806000806060858703121561078057600080fd5b843561078b816106f4565b9350602085013567ffffffffffffffff808211156107a857600080fd5b818701915087601f8301126107bc57600080fd5b8135818111156107cb57600080fd5b8860208285010111156107dd57600080fd5b95986020929092019750949560400135945092505050565b821515815260006020604081840152835180604085015260005b8181101561082b5785810183015185820160600152820161080f565b506000606082860101526060601f19601f830116850101925050509392505050565b801515811461064757600080fd5b6000806000806080858703121561087157600080fd5b843561087c816106f4565b9350602085013561088c816106f4565b9250604085013561089c81610709565b915060608501356108ac8161084d565b939692955090935050565b6000602082840312156108c957600080fd5b81356108d4816106f4565b9392505050565b6001600160e01b031981358181169160048510156109035780818660040360031b1b83161692505b505092915050565b6000808585111561091b57600080fd5b8386111561092857600080fd5b5050820193919092039150565b8183823760009101908152919050565b6000806000806080858703121561095b57600080fd5b8451610966816106f4565b6020860151909450610977816106f4565b604086015190935061098881610709565b60608601519092506108ac8161084d565b6000602082840312156109ab57600080fd5b81516108d4816106f456fea264697066735822122043b62f587bd1dd4f8e47ec71a8974d9f9dc756c63e4261c8e945fd0e1d8cd82364736f6c63430008110033000000000000000000000000b94333ca4de54f79b24294582471c9c336acb7c0

Deployed ByteCode

0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100e8578063c6b295c114610103578063e64624fa14610124578063f2fde38b1461013757600080fd5b8063715018a6146100825780637aa7d3fd1461008c5780638ad2f289146100d5575b600080fd5b61008a61014a565b005b6100c061009a36600461071f565b600160209081526000938452604080852082529284528284209052825290205460ff1681565b60405190151581526020015b60405180910390f35b6100c06100e336600461071f565b61015e565b6000546040516001600160a01b0390911681526020016100cc565b61011661011136600461076a565b610265565b6040516100cc9291906107f5565b61008a61013236600461085b565b610496565b61008a6101453660046108b7565b6105d1565b61015261064a565b61015c60006106a4565b565b600080546001600160a01b03858116911614806101b257506001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff165b806101ea57506001600160a01b03808516600090815260016020908152604080832093871683529281528282208280529052205460ff165b8061022a57506001600160a01b038416600090815260016020908152604080832083805282528083206001600160e01b03198616845290915290205460ff165b8061025d57506001600160a01b0384166000908152600160209081526040808320838052825280832090915290205460ff165b949350505050565b600060608161027485876108db565b9050306001600160a01b038816036103bb57630cdced8360e11b6001600160e01b031982160161030a5760008080806102b0896004818d61090b565b6040516020016102c1929190610935565b6040516020818303038152906040528060200190518101906102e39190610945565b93509350935093506102f784848484610496565b50600195506060945061048d9350505050565b630d021c7560e01b6001600160e01b031982160161037f576000610331866004818a61090b565b604051602001610342929190610935565b6040516020818303038152906040528060200190518101906103649190610999565b905061036f816105d1565b50600192506060915061048d9050565b634757f3ad60e11b6001600160e01b03198216016103ad5761039f61014a565b50600191506060905061048d565b50600091506060905061048d565b6103c633888361015e565b6104295760405162461bcd60e51b815260206004820152602960248201527f44656c656761746f723a2043616c6c657220646f65736e27742068617665207060448201526832b936b4b9b9b4b7b760b91b60648201526084015b60405180910390fd5b866001600160a01b0316848787604051610444929190610935565b60006040518083038185875af1925050503d8060008114610481576040519150601f19603f3d011682016040523d82523d6000602084013e610486565b606091505b5092509250505b94509492505050565b61049e61064a565b6001600160a01b03808516600090815260016020908152604080832093871683529281528282206001600160e01b0319861683529052205460ff161515811515146105cb576001600160a01b03848116600090815260016020908152604080832093871683529281528282206001600160e01b031986168352905220805460ff1916821580159190911790915561057f57816001600160e01b031916836001600160a01b0316856001600160a01b03167f521b363b3401f4d6404e4bd855a3edf8d254a7f55abb97b6d516b66a6f86205e60405160405180910390a46105cb565b816001600160e01b031916836001600160a01b0316856001600160a01b03167f91f81f13bab4e6573f47dda4f090782eb2c9173d3d489ca191b5f4f7355cebe860405160405180910390a45b50505050565b6105d961064a565b6001600160a01b03811661063e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610420565b610647816106a4565b50565b6000546001600160a01b0316331461015c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610420565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461064757600080fd5b6001600160e01b03198116811461064757600080fd5b60008060006060848603121561073457600080fd5b833561073f816106f4565b9250602084013561074f816106f4565b9150604084013561075f81610709565b809150509250925092565b6000806000806060858703121561078057600080fd5b843561078b816106f4565b9350602085013567ffffffffffffffff808211156107a857600080fd5b818701915087601f8301126107bc57600080fd5b8135818111156107cb57600080fd5b8860208285010111156107dd57600080fd5b95986020929092019750949560400135945092505050565b821515815260006020604081840152835180604085015260005b8181101561082b5785810183015185820160600152820161080f565b506000606082860101526060601f19601f830116850101925050509392505050565b801515811461064757600080fd5b6000806000806080858703121561087157600080fd5b843561087c816106f4565b9350602085013561088c816106f4565b9250604085013561089c81610709565b915060608501356108ac8161084d565b939692955090935050565b6000602082840312156108c957600080fd5b81356108d4816106f4565b9392505050565b6001600160e01b031981358181169160048510156109035780818660040360031b1b83161692505b505092915050565b6000808585111561091b57600080fd5b8386111561092857600080fd5b5050820193919092039150565b8183823760009101908152919050565b6000806000806080858703121561095b57600080fd5b8451610966816106f4565b6020860151909450610977816106f4565b604086015190935061098881610709565b60608601519092506108ac8161084d565b6000602082840312156109ab57600080fd5b81516108d4816106f456fea264697066735822122043b62f587bd1dd4f8e47ec71a8974d9f9dc756c63e4261c8e945fd0e1d8cd82364736f6c63430008110033