Skip to content

Commit

Permalink
Merge branch 'contracts/msg-translator-v3' into 'main'
Browse files Browse the repository at this point in the history
feat(contracts): add adv stake msg translator v3

See merge request pantherprotocol/panther-core!1145
  • Loading branch information
vkonst committed Aug 29, 2023
2 parents 3fa9f5e + 89829e1 commit 3d81840
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
65 changes: 65 additions & 0 deletions contracts/contracts/staking/AdvancedStakeV3ActionMsgTranslator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: BUSL-1.1
// SPDX-FileCopyrightText: Copyright 2023 Panther Ventures Limited Gibraltar
pragma solidity 0.8.16;

import "./interfaces/IRewardAdviser.sol";
import "./interfaces/IActionMsgReceiver.sol";
import { ADVANCED_STAKE, ADVANCED_STAKE_V3, ADVANCED_UNSTAKE_V3 } from "./actions/Constants.sol";

/**
* @title AdvancedStakeV3ActionMsgTranslator
* @notice It processes action messages for stakes of the `advanced-v3` type.
* @dev It "translates" the `action` in messages so that other contracts, which
* are "unaware" of "v3" stake type, may process this type stakes exactly like
* they process `advanced` type stakes.
* It shall be registered with the `RewardMaster` as the "RewardAdviser" for
* `advanced-v3` type stakes and the "ActionOracle" for `advanced` type stakes.
* Being called `getRewardAdvice` by the RewardMaster for a message with the
* `advanced-v3` STAKE action, it replaces the `action` to be the `advanced`
* (but not `advanced-v3`) STAKE action.
* Then it calls `onAction` on the RewardMaster with the substituted message.
* When called back, the latter processes the substituted action message as if
* it is the `advanced` (not `advanced-v3`) STAKE action.
*/
contract AdvancedStakeV3ActionMsgTranslator is IRewardAdviser {
// solhint-disable var-name-mixedcase

/// @notice RewardMaster contract instance
address private immutable REWARD_MASTER;

// solhint-enable var-name-mixedcase

constructor(address rewardMaster) {
require(rewardMaster != address(0), "Zero address");

REWARD_MASTER = rewardMaster;
}

/// @dev To be called by the {RewardMaster} for `advanced-v3` type actions.
/// It makes the `action` to look like the `advanced` (not "v3") type action
/// and calls the {RewardMaster} back simulating a "new" action message.
function getRewardAdvice(bytes4 action, bytes memory message)
external
override
returns (Advice memory)
{
require(msg.sender == REWARD_MASTER, "AMT: unauthorized");

if (action == ADVANCED_STAKE_V3) {
// Replace the action and return the message back to REWARD_MASTER
IActionMsgReceiver(REWARD_MASTER).onAction(ADVANCED_STAKE, message);
} else {
require(action == ADVANCED_UNSTAKE_V3, "AMT: unsupported action");
}

// Return "zero" advice
return
Advice(
address(0), // createSharesFor
0, // sharesToCreate
address(0), // redeemSharesFrom
0, // sharesToRedeem
address(0) // sendRewardTo
);
}
}
12 changes: 12 additions & 0 deletions contracts/contracts/staking/actions/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ bytes4 constant ADVANCED_STAKE_V2 = 0x1954e321;
// bytes4(keccak256(abi.encodePacked(bytes4(keccak256("unstake"), ADVANCED_STAKE_V2_TYPE)))
bytes4 constant ADVANCED_UNSTAKE_V2 = 0x6a8ecb81;

// The "stake type" for the "advance staking"
// bytes4(keccak256("advanced-v3"))
bytes4 constant ADVANCED_STAKE_V3_TYPE = 0x466b3169;

// STAKE "action type" for the "advanced staking V3"
// bytes4(keccak256(abi.encodePacked(bytes4(keccak256("stake"), ADVANCED_STAKE_V3_TYPE)))
bytes4 constant ADVANCED_STAKE_V3 = 0x2991610f;

// UNSTAKE "action type" for the "advanced staking v2"
// bytes4(keccak256(abi.encodePacked(bytes4(keccak256("unstake"), ADVANCED_STAKE_V3_TYPE)))
bytes4 constant ADVANCED_UNSTAKE_V3 = 0xc0873111;

// PRP grant type for the "advanced" stake
// bytes4(keccak256("forAdvancedStakeGrant"))
bytes4 constant FOR_ADVANCED_STAKE_GRANT = 0x31a180d4;
Expand Down
43 changes: 43 additions & 0 deletions contracts/test/staking/advancedStakeV3ActionMsgTranslator.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers';
import {expect} from 'chai';
import hardhat from 'hardhat';

const {ethers} = hardhat;

import {AdvancedStakeV3ActionMsgTranslator} from '../../types/contracts';

describe.only('AdvancedStakeV3ActionMsgTranslator', () => {
const advStakeV3 = '0x2991610f';
const invalidAction = '0x12345678';
const message = '0x00';

let translator: AdvancedStakeV3ActionMsgTranslator;
let user: SignerWithAddress;
let rewardMaster: SignerWithAddress;

before(async () => {
[user, rewardMaster] = await ethers.getSigners();

const AdvancedStakeV3ActionMsgTranslator =
await ethers.getContractFactory(
'AdvancedStakeV3ActionMsgTranslator',
);
translator = (await AdvancedStakeV3ActionMsgTranslator.deploy(
rewardMaster.address,
)) as AdvancedStakeV3ActionMsgTranslator;
});

it('should throw when executed by unauthorized account', async () => {
await expect(
translator.connect(user).getRewardAdvice(advStakeV3, message),
).to.be.revertedWith('AMT: unauthorized');
});

it('should throw when executed with invalid action type', async () => {
await expect(
translator
.connect(rewardMaster)
.getRewardAdvice(invalidAction, message),
).to.be.revertedWith('AMT: unsupported action');
});
});

0 comments on commit 3d81840

Please sign in to comment.