Skip to content

Commit

Permalink
add two types of bond
Browse files Browse the repository at this point in the history
  • Loading branch information
bxmmm1 committed Oct 20, 2023
1 parent 6ab291e commit d887d96
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 17 deletions.
2 changes: 1 addition & 1 deletion script/DeployPuffer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ contract DeployPuffer is BaseScript {
// Read guardians module variable
address payable guardiansModule = payable(stdJson.readAddress(guardiansDeployment, ".guardianModule"));

NoRestakingStrategy noRestaking = new NoRestakingStrategy(address(accessManager));
NoRestakingStrategy noRestaking = new NoRestakingStrategy(address(accessManager), pufferProtocol);

// Initialize the Pool
pufferProtocol.initialize({
Expand Down
3 changes: 2 additions & 1 deletion script/SetupAccess.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ contract SetupAccess is BaseScript {
}

function _setupPufferProtocolRoles() internal {
bytes4[] memory selectors = new bytes4[](8);
bytes4[] memory selectors = new bytes4[](9);
selectors[0] = PufferProtocol.setProtocolFeeRate.selector;
selectors[1] = PufferProtocol.setSmoothingCommitment.selector;
selectors[2] = PufferProtocol.createPufferStrategy.selector;
Expand All @@ -88,6 +88,7 @@ contract SetupAccess is BaseScript {
selectors[5] = PufferProtocol.changeStrategy.selector;
selectors[6] = bytes4(hex"4f1ef286"); // signature for UUPS.upgradeToAndCall(address newImplementation, bytes memory data)
selectors[7] = PufferProtocol.setGuardiansFeeRate.selector;
selectors[8] = PufferProtocol.setWithdrawalPoolRate.selector;

accessManager.setTargetFunctionRole(address(pufferProtocol), selectors, ROLE_ID_DAO);

Expand Down
10 changes: 8 additions & 2 deletions src/NoRestakingStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ pragma solidity >=0.8.0 <0.9.0;

import { AccessManaged } from "openzeppelin/access/manager/AccessManaged.sol";
import { IPufferStrategy } from "puffer/interface/IPufferStrategy.sol";
import { PufferProtocol } from "puffer/PufferProtocol.sol";
import { AbstractVault } from "puffer/AbstractVault.sol";

/**
* @title NoRestakingStrategy
* @author Puffer Finance
* @notice NoRestakingStrategy
* @custom:security-contact [email protected]
*/
contract NoRestakingStrategy is IPufferStrategy, AccessManaged {
contract NoRestakingStrategy is IPufferStrategy, AccessManaged, AbstractVault {
/**
* @notice Beacon chain deposit contract
*/
Expand All @@ -21,7 +23,11 @@ contract NoRestakingStrategy is IPufferStrategy, AccessManaged {
*/
bytes32 public constant NAME = bytes32("NO_RESTAKING");

constructor(address initialAuthority) AccessManaged(initialAuthority) { }
constructor(address initialAuthority, PufferProtocol puffer)
payable
AccessManaged(initialAuthority)
AbstractVault(puffer)
{ }

/**
* @notice Can Receive ETH donations
Expand Down
48 changes: 36 additions & 12 deletions src/PufferProtocol.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad
uint256 internal constant _32_ETHER = 32 ether;

/**
* @dev ETH Amount required to be deposited as a bond by node operator
* @dev ETH Amount required to be deposited as a bond if the node operator uses SGX
*/
uint256 internal constant _VALIDATOR_BOND = 1 ether;
uint256 internal constant _SGX_VALIDATOR_BOND = 1 ether;

/**
* @dev ETH Amount required to be deposited as a bond if the node operator doesn't use SGX
*/
uint256 internal constant _NO_SGX_VALIDATOR_BOND = 2 ether;

/**
* @dev Default "NO_RESTAKING" strategy
Expand Down Expand Up @@ -72,7 +77,7 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad
*/
Safe public immutable GUARDIANS;

constructor(Safe guardians, address payable treasury, address strategyBeacon) {
constructor(Safe guardians, address payable treasury, address strategyBeacon) payable {
PUFFER_STRATEGY_BEACON = strategyBeacon;
TREASURY = treasury;
GUARDIANS = guardians;
Expand Down Expand Up @@ -107,9 +112,11 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad
function registerValidatorKey(ValidatorKeyData calldata data, bytes32 strategyName) external payable {
ProtocolStorage storage $ = _getPufferProtocolStorage();

_checkValidatorRegistrationInputs(data, strategyName, $);
uint256 validatorBond = data.raveEvidence.length > 0 ? _SGX_VALIDATOR_BOND : _NO_SGX_VALIDATOR_BOND;

uint256 pufETHReceived = $.pool.depositETH{ value: _VALIDATOR_BOND }();
_checkValidatorRegistrationInputs($, data, strategyName, validatorBond);

uint256 pufETHReceived = $.pool.depositETH{ value: validatorBond }();

// Save the validator data to storage
Validator memory validator;
Expand All @@ -119,7 +126,7 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad
validator.strategy = address($.strategies[strategyName]);
validator.bond = SafeCastLib.toUint64(pufETHReceived);
validator.commitmentStartDate = SafeCastLib.toUint40(block.timestamp);
validator.commitmentAmount = SafeCastLib.toUint64(msg.value);
validator.commitmentAmount = SafeCastLib.toUint64(msg.value - validatorBond);
validator.node = msg.sender;

uint256 validatorIndex = $.pendingValidatorIndicies[strategyName];
Expand All @@ -131,7 +138,7 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad

emit ValidatorKeyRegistered(data.blsPubKey, validatorIndex);

_transferFunds($);
_transferFunds($, validatorBond);
}

function getDepositDataRoot(bytes calldata pubKey, bytes calldata signature, bytes calldata withdrawalCredentials)
Expand Down Expand Up @@ -213,7 +220,7 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad

emit SmoothingCommitmentPaid(validator.pubKey, block.timestamp, msg.value);

_transferFunds($);
_transferFunds($, 0);
}

/**
Expand Down Expand Up @@ -330,14 +337,30 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad
_setSmoothingCommitment(strategyName, smoothingCommitment);
}

/**
* @inheritdoc IPufferProtocol
*/
function setProtocolFeeRate(uint256 protocolFeeRate) external restricted {
_setProtocolFeeRate(protocolFeeRate);
}

/**
* @inheritdoc IPufferProtocol
*/
function setGuardiansFeeRate(uint256 newRate) external restricted {
_setGuardiansFeeRate(newRate);
}

/**
* @inheritdoc IPufferProtocol
*/
function setWithdrawalPoolRate(uint256 newRate) external restricted {
_setWithdrawalPoolRate(newRate);
}

/**
* @inheritdoc IPufferProtocol
*/
function getValidatorLimitPerInterval() external view returns (uint256) {
ProtocolStorage storage $ = _getPufferProtocolStorage();
return uint256($.validatorLimitPerInterval);
Expand Down Expand Up @@ -499,8 +522,8 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad
emit CommitmentChanged(strategyName, oldSmoothingCommitment, smoothingCommitment);
}

function _transferFunds(ProtocolStorage storage $) internal {
uint256 amount = msg.value - _VALIDATOR_BOND;
function _transferFunds(ProtocolStorage storage $, uint256 bond) internal {
uint256 amount = msg.value - bond;

uint256 treasuryAmount = _sendETH(TREASURY, amount, $.protocolFeeRate);
uint256 withdrawalPoolAmount = _sendETH(address($.withdrawalPool), amount, $.withdrawalPoolRate);
Expand Down Expand Up @@ -617,9 +640,10 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad
}

function _checkValidatorRegistrationInputs(
ProtocolStorage storage $,
ValidatorKeyData calldata data,
bytes32 strategyName,
ProtocolStorage storage $
uint256 validatorBond
) internal {
// +1 To check if this registration would go over the limit
if (($.numberOfValidatorsRegisteredInThisInterval + 1) > $.validatorLimitPerInterval) {
Expand Down Expand Up @@ -652,7 +676,7 @@ contract PufferProtocol is IPufferProtocol, AccessManagedUpgradeable, UUPSUpgrad

uint256 smoothingCommitment = $.smoothingCommitments[strategyName];

if (msg.value != (smoothingCommitment + _VALIDATOR_BOND)) {
if (msg.value != (smoothingCommitment + validatorBond)) {
revert InvalidETHAmount();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/PufferStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ contract PufferStrategy is IPufferStrategy, Initializable, AccessManagedUpgradea
IEigenPod eigenPod;
}

constructor(IEigenPodManager eigenPodManager) {
constructor(IEigenPodManager eigenPodManager) payable {
EIGEN_POD_MANAGER = eigenPodManager;
}

Expand Down
24 changes: 24 additions & 0 deletions src/interface/IPufferProtocol.sol
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,30 @@ interface IPufferProtocol {
*/
function setStrategyWeights(bytes32[] calldata newStrategyWeights) external;

/**
* @notice Sets the protocol fee rate
* @dev 1% equals `1 * FixedPointMathLib.WAD`
*
* Restricted to DAO
*/
function setProtocolFeeRate(uint256 protocolFeeRate) external;

/**
* @notice Sets the withdrawl pool rate

Check failure on line 252 in src/interface/IPufferProtocol.sol

View workflow job for this annotation

GitHub Actions / codespell

withdrawl ==> withdrawal, withdraw
* @dev 1% equals `1 * FixedPointMathLib.WAD`
*
* Restricted to DAO
*/
function setWithdrawalPoolRate(uint256 newRate) external;

/**
* @notice Sets guardians fee rate
* @dev 1% equals `1 * FixedPointMathLib.WAD`
*
* Restricted to DAO
*/
function setGuardiansFeeRate(uint256 newRate) external;

/**
* @notice Sets the validator limit per interval to `newLimit`
* @dev Restricted to DAO
Expand Down
26 changes: 26 additions & 0 deletions test/unit/EnclaveVerifier.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity >=0.8.0 <0.9.0;

import { Test } from "forge-std/Test.sol";
import { EnclaveVerifier } from "puffer/EnclaveVerifier.sol";
import { IEnclaveVerifier } from "puffer/interface/IEnclaveVerifier.sol";
import { RaveEvidence } from "puffer/struct/RaveEvidence.sol";
import { MockEvidence } from "rave-test/mocks/MockEvidence.sol";
import { TestHelper } from "../helpers/TestHelper.sol";
Expand Down Expand Up @@ -61,6 +62,31 @@ contract EnclaveVerifierTest is TestHelper, TestBase {
_verifyValidatorPubKey(new Guardian3RaveEvidence());
}

function testVerifyingStaleEvidence() public {
Guardian3RaveEvidence raveEvidence = new Guardian3RaveEvidence();

vm.roll(5000);

RaveEvidence memory evidence = RaveEvidence({
report: raveEvidence.report(),
signature: raveEvidence.sig(),
leafX509CertDigest: keccak256(raveEvidence.signingCert())
});

bytes32 mrenclave = raveEvidence.mrenclave();
bytes32 mrsigner = raveEvidence.mrsigner();
bytes32 commitment = keccak256(raveEvidence.payload());

vm.expectRevert(IEnclaveVerifier.StaleEvidence.selector);
verifier.verifyEvidence({
blockNumber: 0,
evidence: evidence,
raveCommitment: commitment,
mrenclave: mrenclave,
mrsigner: mrsigner
});
}

// Verify rave evidence
function _verifyValidatorPubKey(MockEvidence raveEvidence) public {
verifier.addLeafX509(raveEvidence.signingCert());
Expand Down
28 changes: 28 additions & 0 deletions test/unit/PufferProtocol.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ValidatorKeyData } from "puffer/struct/ValidatorKeyData.sol";
import { Status } from "puffer/struct/Status.sol";
import { Validator } from "puffer/struct/Validator.sol";
import { PufferProtocol } from "puffer/PufferProtocol.sol";
import { PufferStrategy } from "puffer/PufferStrategy.sol";
import { console } from "forge-std/console.sol";
import { ROLE_ID_DAO } from "script/SetupAccess.s.sol";

Expand Down Expand Up @@ -65,6 +66,8 @@ contract PufferProtocolTest is TestHelper, TestBase {
// Setup
function testSetup() public {
assertTrue(address(pufferProtocol.getWithdrawalPool()) != address(0), "non zero address");
address strat = pufferProtocol.getStrategyAddress(NO_RESTAKING);

Check failure on line 69 in test/unit/PufferProtocol.t.sol

View workflow job for this annotation

GitHub Actions / codespell

strat ==> start, strata
assertEq(PufferStrategy(payable(strat)).NAME(), NO_RESTAKING, "bad name");

Check failure on line 70 in test/unit/PufferProtocol.t.sol

View workflow job for this annotation

GitHub Actions / codespell

strat ==> start, strata
}

function testEmptyQueue() public {
Expand Down Expand Up @@ -311,6 +314,31 @@ contract PufferProtocolTest is TestHelper, TestBase {
assertEq(pufferProtocol.getProtocolFeeRate(), rate, "new rate");
}

function testSetGuardiansFeeRateOverTheLimit() public {
uint256 rate = 30 * FixedPointMathLib.WAD;
vm.expectRevert(IPufferProtocol.InvalidData.selector);
pufferProtocol.setGuardiansFeeRate(rate);
}

function testSetProtocolFeeRateOverTheLimit() public {
uint256 rate = 30 * FixedPointMathLib.WAD;
vm.expectRevert(IPufferProtocol.InvalidData.selector);
pufferProtocol.setProtocolFeeRate(rate);
}

function testSetWithdrawalPoolRateOverTheLimit() public {
uint256 rate = 30 * FixedPointMathLib.WAD;
vm.expectRevert(IPufferProtocol.InvalidData.selector);
pufferProtocol.setWithdrawalPoolRate(rate);
}

function testChangeStrategy() public {
address strategy = pufferProtocol.getStrategyAddress(NO_RESTAKING);
pufferProtocol.changeStrategy(NO_RESTAKING, PufferStrategy(payable(address(5))));
address strategyAfterChange = pufferProtocol.getStrategyAddress(NO_RESTAKING);
assertTrue(strategy != strategyAfterChange, "straetgy did not change");
}

function _registerValidatorKey(bytes32 pubKeyPart, bytes32 strategyName) internal {
uint256 smoothingCommitment = pufferProtocol.getSmoothingCommitment(strategyName);

Expand Down

0 comments on commit d887d96

Please sign in to comment.