ETH Price: $1,660.72 (+4.06%)
Gas: 17 Gwei
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value
0x60e06040140839372022-01-26 22:30:17609 days 19 hrs ago1643236217IN
 Create: StakeRewardAdviser
0 ETH0.052173110

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
StakeRewardAdviser

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 800 runs

Other Settings:
default evmVersion
File 1 of 5 : StakeRewardAdviser.sol
// SPDX-License-Identifier: UNLICENSED
// solhint-disable-next-line compiler-fixed, compiler-gt-0_8
pragma solidity ^0.8.0;

import "./actions/StakingMsgProcessor.sol";
import "./interfaces/IRewardAdviser.sol";
import "./utils/Utils.sol";

/**
 * @title StakeRewardAdviser
 * @notice It "advises" the "RewardMaster" on staking rewards ("shares").
 * @dev It acts as the "RewardAdviser" for the "RewardMaster": the latter calls
 * this contract to process messages from the "Staking" contract.
 */
contract StakeRewardAdviser is StakingMsgProcessor, Utils, IRewardAdviser {
    // solhint-disable var-name-mixedcase
    bytes4 private immutable STAKED;
    bytes4 private immutable UNSTAKED;
    uint256 public immutable FACTOR;
    // solhint-enable var-name-mixedcase

    uint256 private constant SCALE = 1e9;

    constructor(bytes4 stakeType, uint256 stakeAmountToSharesScaledFactor) {
        require(
            stakeType != bytes4(0) && stakeAmountToSharesScaledFactor != 0,
            "PSA:E1"
        );
        STAKED = _encodeStakeActionType(stakeType);
        UNSTAKED = _encodeUnstakeActionType(stakeType);
        FACTOR = stakeAmountToSharesScaledFactor;
    }

    function getRewardAdvice(bytes4 action, bytes memory message)
        external
        view
        override
        returns (Advice memory)
    {
        (address staker, uint96 amount, , , , , ) = _unpackStakingActionMsg(
            message
        );
        require(staker != address(0), "PSA: unexpected zero staker");
        require(amount != 0, "PSA: unexpected zero amount");

        uint256 shares = (uint256(amount) * FACTOR) / SCALE;

        if (action == STAKED) {
            return
                Advice(
                    staker, // createSharesFor
                    safe96(shares), // sharesToCreate
                    address(0), // redeemSharesFrom
                    0, // sharesToRedeem
                    address(0) // sendRewardTo
                );
        }
        if (action == UNSTAKED) {
            return
                Advice(
                    address(0), // createSharesFor
                    0, // sharesToCreate
                    staker, // redeemSharesFrom
                    safe96(shares), // sharesToRedeem
                    staker // sendRewardTo
                );
        }

        revert("PSA: unsupported action");
    }
}

File 2 of 5 : StakingMsgProcessor.sol
// SPDX-License-Identifier: UNLICENSED
// solhint-disable-next-line compiler-fixed, compiler-gt-0_8
pragma solidity ^0.8.0;

import "../interfaces/IStakingTypes.sol";

abstract contract StakingMsgProcessor {
    bytes4 internal constant STAKE_ACTION = bytes4(keccak256("stake"));
    bytes4 internal constant UNSTAKE_ACTION = bytes4(keccak256("unstake"));

    function _encodeStakeActionType(bytes4 stakeType)
        internal
        pure
        returns (bytes4)
    {
        return bytes4(keccak256(abi.encodePacked(STAKE_ACTION, stakeType)));
    }

    function _encodeUnstakeActionType(bytes4 stakeType)
        internal
        pure
        returns (bytes4)
    {
        return bytes4(keccak256(abi.encodePacked(UNSTAKE_ACTION, stakeType)));
    }

    function _packStakingActionMsg(
        address staker,
        IStakingTypes.Stake memory stake,
        bytes calldata data
    ) internal pure returns (bytes memory) {
        return
            abi.encodePacked(
                staker, // address
                stake.amount, // uint96
                stake.id, // uint32
                stake.stakedAt, // uint32
                stake.lockedTill, // uint32
                stake.claimedAt, // uint32
                data // bytes
            );
    }

    // For efficiency we use "packed" (rather than "ABI") encoding.
    // It results in shorter data, but requires custom unpack function.
    function _unpackStakingActionMsg(bytes memory message)
        internal
        pure
        returns (
            address staker,
            uint96 amount,
            uint32 id,
            uint32 stakedAt,
            uint32 lockedTill,
            uint32 claimedAt,
            bytes memory data
        )
    {
        // staker, amount, id and 3 timestamps occupy exactly 48 bytes
        // (`data` may be of zero length)
        require(message.length >= 48, "SMP: unexpected msg length");

        uint256 stakerAndAmount;
        uint256 idAndStamps;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            // the 1st word (32 bytes) contains the `message.length`
            // we need the (entire) 2nd word ..
            stakerAndAmount := mload(add(message, 0x20))
            // .. and (16 bytes of) the 3rd word
            idAndStamps := mload(add(message, 0x40))
        }

        staker = address(uint160(stakerAndAmount >> 96));
        amount = uint96(stakerAndAmount & 0xFFFFFFFFFFFFFFFFFFFFFFFF);

        id = uint32((idAndStamps >> 224) & 0xFFFFFFFF);
        stakedAt = uint32((idAndStamps >> 192) & 0xFFFFFFFF);
        lockedTill = uint32((idAndStamps >> 160) & 0xFFFFFFFF);
        claimedAt = uint32((idAndStamps >> 128) & 0xFFFFFFFF);

        uint256 dataLength = message.length - 48;
        data = new bytes(dataLength);
        for (uint256 i = 0; i < dataLength; i++) {
            data[i] = message[i + 48];
        }
    }
}

File 3 of 5 : IRewardAdviser.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IRewardAdviser {
    struct Advice {
        // advice on new "shares" (in the reward pool) to create
        address createSharesFor;
        uint96 sharesToCreate;
        // advice on "shares" to redeem
        address redeemSharesFrom;
        uint96 sharesToRedeem;
        // advice on address the reward against redeemed shares to send to
        address sendRewardTo;
    }

    function getRewardAdvice(bytes4 action, bytes memory message)
        external
        returns (Advice memory);
}

File 4 of 5 : Utils.sol
// SPDX-License-Identifier: MIT
// solhint-disable-next-line compiler-fixed, compiler-gt-0_8
pragma solidity ^0.8.0;

abstract contract Utils {
    function safe32(uint256 n) internal pure returns (uint32) {
        require(n < 2**32, "UNSAFE32");
        return uint32(n);
    }

    function safe96(uint256 n) internal pure returns (uint96) {
        require(n < 2**96, "UNSAFE96");
        return uint96(n);
    }

    function safe128(uint256 n) internal pure returns (uint128) {
        require(n < 2**128, "UNSAFE128");
        return uint128(n);
    }

    function safe160(uint256 n) internal pure returns (uint160) {
        require(n < 2**160, "UNSAFE160");
        return uint160(n);
    }

    function safe32TimeNow() internal view returns (uint32) {
        return safe32(timeNow());
    }

    function safe32BlockNow() internal view returns (uint32) {
        return safe32(blockNow());
    }

    /// @dev Returns the current block timestamp (added to ease testing)
    function timeNow() internal view virtual returns (uint256) {
        return block.timestamp;
    }

    /// @dev Returns the current block number (added to ease testing)
    function blockNow() internal view virtual returns (uint256) {
        return block.number;
    }
}

File 5 of 5 : IStakingTypes.sol
// SPDX-License-Identifier: MIT
// solhint-disable-next-line compiler-fixed, compiler-gt-0_8
pragma solidity ^0.8.0;

interface IStakingTypes {
    // Stake type terms
    struct Terms {
        // if stakes of this kind allowed
        bool isEnabled;
        // if messages on stakes to be sent to the {RewardMaster}
        bool isRewarded;
        // limit on the minimum amount staked, no limit if zero
        uint32 minAmountScaled;
        // limit on the maximum amount staked, no limit if zero
        uint32 maxAmountScaled;
        // Stakes not accepted before this time, has no effect if zero
        uint32 allowedSince;
        // Stakes not accepted after this time, has no effect if zero
        uint32 allowedTill;
        // One (at least) of the following three params must be non-zero
        // if non-zero, overrides both `exactLockPeriod` and `minLockPeriod`
        uint32 lockedTill;
        // ignored if non-zero `lockedTill` defined, overrides `minLockPeriod`
        uint32 exactLockPeriod;
        // has effect only if both `lockedTill` and `exactLockPeriod` are zero
        uint32 minLockPeriod;
    }

    struct Stake {
        // index in the `Stake[]` array of `stakes`
        uint32 id;
        // defines Terms
        bytes4 stakeType;
        // time this stake was created at
        uint32 stakedAt;
        // time this stake can be claimed at
        uint32 lockedTill;
        // time this stake was claimed at (unclaimed if 0)
        uint32 claimedAt;
        // amount of tokens on this stake (assumed to be less 1e27)
        uint96 amount;
        // address stake voting power is delegated to
        address delegatee;
    }
}

Settings
{
  "metadata": {
    "bytecodeHash": "none",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 800
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"bytes4","name":"stakeType","type":"bytes4"},{"internalType":"uint256","name":"stakeAmountToSharesScaledFactor","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"action","type":"bytes4"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"getRewardAdvice","outputs":[{"components":[{"internalType":"address","name":"createSharesFor","type":"address"},{"internalType":"uint96","name":"sharesToCreate","type":"uint96"},{"internalType":"address","name":"redeemSharesFrom","type":"address"},{"internalType":"uint96","name":"sharesToRedeem","type":"uint96"},{"internalType":"address","name":"sendRewardTo","type":"address"}],"internalType":"struct IRewardAdviser.Advice","name":"","type":"tuple"}],"stateMutability":"view","type":"function"}]

60e060405234801561001057600080fd5b5060405161092638038061092683398101604081905261002f91610124565b6001600160e01b031982161580159061004757508015155b6100805760405162461bcd60e51b81526020600482015260066024820152655053413a453160d01b604482015260640160405180910390fd5b610089826100b5565b6001600160e01b03191660805261009f826100f9565b6001600160e01b03191660a05260c0525061015d565b60405163c3a0479560e01b60208201526001600160e01b0319821660248201526000906028015b604051602081830303815290604052805190602001209050919050565b604051637a3e3dfd60e01b60208201526001600160e01b0319821660248201526000906028016100dc565b60008060408385031215610136578182fd5b82516001600160e01b03198116811461014d578283fd5b6020939093015192949293505050565b60805160e01c60e01b60a05160e01c60e01b60c05161078861019e60003960008181604001526101fa015260006102cb0152600061023b01526107886000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806335815b951461003b578063e9cb032414610075575b600080fd5b6100627f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6100886100833660046105e3565b6100ed565b60405161006c9190600060a0820190506001600160a01b0380845116835260208401516bffffffffffffffffffffffff808216602086015282604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081018290529080610122846103c5565b50505050509150915060006001600160a01b0316826001600160a01b031614156101935760405162461bcd60e51b815260206004820152601b60248201527f5053413a20756e6578706563746564207a65726f207374616b6572000000000060448201526064015b60405180910390fd5b6bffffffffffffffffffffffff81166101ee5760405162461bcd60e51b815260206004820152601b60248201527f5053413a20756e6578706563746564207a65726f20616d6f756e740000000000604482015260640161018a565b6000633b9aca0061022d7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff85166106fe565b61023791906106de565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160e01b031916866001600160e01b03191614156102c9576040518060a00160405280846001600160a01b0316815260200161029883610581565b6bffffffffffffffffffffffff1681526000602082018190526040820181905260609091015293506103bf92505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160e01b031916866001600160e01b0319161415610377576040518060a0016040528060006001600160a01b0316815260200160006bffffffffffffffffffffffff168152602001846001600160a01b0316815260200161034d83610581565b6bffffffffffffffffffffffff168152602001846001600160a01b031681525093505050506103bf565b60405162461bcd60e51b815260206004820152601760248201527f5053413a20756e737570706f7274656420616374696f6e000000000000000000604482015260640161018a565b92915050565b60008060008060008060606030885110156104225760405162461bcd60e51b815260206004820152601a60248201527f534d503a20756e6578706563746564206d7367206c656e677468000000000000604482015260640161018a565b602088015160408901518951606083901c99506bffffffffffffffffffffffff8316985060e082901c975063ffffffff60c083901c8116975060a083901c81169650608083901c16945060009061047b9060309061071d565b90508067ffffffffffffffff8111156104a457634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156104ce576020820181803683370190505b50935060005b81811015610572578b6104e88260306106c6565b8151811061050657634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b85828151811061053157634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061056a81610734565b9150506104d4565b50505050919395979092949650565b60006c0100000000000000000000000082106105df5760405162461bcd60e51b815260206004820152600860248201527f554e534146453936000000000000000000000000000000000000000000000000604482015260640161018a565b5090565b600080604083850312156105f5578182fd5b82357fffffffff0000000000000000000000000000000000000000000000000000000081168114610624578283fd5b9150602083013567ffffffffffffffff80821115610640578283fd5b818501915085601f830112610653578283fd5b81358181111561066557610665610765565b604051601f8201601f19908116603f0116810190838211818310171561068d5761068d610765565b816040528281528860208487010111156106a5578586fd5b82602086016020830137856020848301015280955050505050509250929050565b600082198211156106d9576106d961074f565b500190565b6000826106f957634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156107185761071861074f565b500290565b60008282101561072f5761072f61074f565b500390565b60006000198214156107485761074861074f565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000804000a4ab0941a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e8

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100365760003560e01c806335815b951461003b578063e9cb032414610075575b600080fd5b6100627f00000000000000000000000000000000000000000000000000000000000003e881565b6040519081526020015b60405180910390f35b6100886100833660046105e3565b6100ed565b60405161006c9190600060a0820190506001600160a01b0380845116835260208401516bffffffffffffffffffffffff808216602086015282604087015116604086015280606087015116606086015250508060808501511660808401525092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081018290529080610122846103c5565b50505050509150915060006001600160a01b0316826001600160a01b031614156101935760405162461bcd60e51b815260206004820152601b60248201527f5053413a20756e6578706563746564207a65726f207374616b6572000000000060448201526064015b60405180910390fd5b6bffffffffffffffffffffffff81166101ee5760405162461bcd60e51b815260206004820152601b60248201527f5053413a20756e6578706563746564207a65726f20616d6f756e740000000000604482015260640161018a565b6000633b9aca0061022d7f00000000000000000000000000000000000000000000000000000000000003e86bffffffffffffffffffffffff85166106fe565b61023791906106de565b90507f1e4d02b5000000000000000000000000000000000000000000000000000000006001600160e01b031916866001600160e01b03191614156102c9576040518060a00160405280846001600160a01b0316815260200161029883610581565b6bffffffffffffffffffffffff1681526000602082018190526040820181905260609091015293506103bf92505050565b7f493bdf45000000000000000000000000000000000000000000000000000000006001600160e01b031916866001600160e01b0319161415610377576040518060a0016040528060006001600160a01b0316815260200160006bffffffffffffffffffffffff168152602001846001600160a01b0316815260200161034d83610581565b6bffffffffffffffffffffffff168152602001846001600160a01b031681525093505050506103bf565b60405162461bcd60e51b815260206004820152601760248201527f5053413a20756e737570706f7274656420616374696f6e000000000000000000604482015260640161018a565b92915050565b60008060008060008060606030885110156104225760405162461bcd60e51b815260206004820152601a60248201527f534d503a20756e6578706563746564206d7367206c656e677468000000000000604482015260640161018a565b602088015160408901518951606083901c99506bffffffffffffffffffffffff8316985060e082901c975063ffffffff60c083901c8116975060a083901c81169650608083901c16945060009061047b9060309061071d565b90508067ffffffffffffffff8111156104a457634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156104ce576020820181803683370190505b50935060005b81811015610572578b6104e88260306106c6565b8151811061050657634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b85828151811061053157634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061056a81610734565b9150506104d4565b50505050919395979092949650565b60006c0100000000000000000000000082106105df5760405162461bcd60e51b815260206004820152600860248201527f554e534146453936000000000000000000000000000000000000000000000000604482015260640161018a565b5090565b600080604083850312156105f5578182fd5b82357fffffffff0000000000000000000000000000000000000000000000000000000081168114610624578283fd5b9150602083013567ffffffffffffffff80821115610640578283fd5b818501915085601f830112610653578283fd5b81358181111561066557610665610765565b604051601f8201601f19908116603f0116810190838211818310171561068d5761068d610765565b816040528281528860208487010111156106a5578586fd5b82602086016020830137856020848301015280955050505050509250929050565b600082198211156106d9576106d961074f565b500190565b6000826106f957634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156107185761071861074f565b500290565b60008282101561072f5761072f61074f565b500390565b60006000198214156107485761074861074f565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000804000a

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

4ab0941a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e8

-----Decoded View---------------
Arg [0] : stakeType (bytes4): 0x4ab0941a
Arg [1] : stakeAmountToSharesScaledFactor (uint256): 1000

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 4ab0941a00000000000000000000000000000000000000000000000000000000
Arg [1] : 00000000000000000000000000000000000000000000000000000000000003e8


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

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