Skip to content

Commit

Permalink
automatically delegate on deposit transaction & add strategist allowa…
Browse files Browse the repository at this point in the history
…nce to undelegate
  • Loading branch information
sparrowDom committed Jan 10, 2025
1 parent 0b5aea3 commit 19c60a7
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ contract SonicStakingStrategy is SonicValidatorDelegator {
function _deposit(address _asset, uint256 _amount) internal virtual {
require(_amount > 0, "Must deposit something");

_delegate(_amount);
emit Deposit(_asset, address(0), _amount);
}

Expand Down
46 changes: 34 additions & 12 deletions contracts/contracts/strategies/sonic/SonicValidatorDelegator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ abstract contract SonicValidatorDelegator is InitializableAbstractStrategy {
/// @notice List of supported validator IDs that can be delegated to
uint256[] public supportedValidators;

/// @notice Default validator id to deposit to
uint256 public defaultValidatorId;

struct WithdrawRequest {
uint256 validatorId;
uint256 undelegatedAmount;
Expand Down Expand Up @@ -55,6 +58,7 @@ abstract contract SonicValidatorDelegator is InitializableAbstractStrategy {
event RegistratorChanged(address indexed newAddress);
event SupportedValidator(uint256 indexed validatorId);
event UnsupportedValidator(uint256 indexed validatorId);
event DefaultValidatorIdChanged(uint256 indexed validatorId);

/// @dev Throws if called by any account other than the Registrator
modifier onlyRegistrator() {
Expand All @@ -65,6 +69,16 @@ abstract contract SonicValidatorDelegator is InitializableAbstractStrategy {
_;
}

/// @dev Throws if called by any account other than the Registrator or Strategist
modifier onlyRegistratorOrStrategist() {
require(
msg.sender == validatorRegistrator ||
msg.sender == IVault(vaultAddress).strategistAddr(),
"Caller is not the Registrator or Strategist"
);
_;
}

constructor(
BaseStrategyConfig memory _baseConfig,
address _wrappedSonic,
Expand Down Expand Up @@ -125,30 +139,28 @@ abstract contract SonicValidatorDelegator is InitializableAbstractStrategy {
}

/**
* @notice Delegate from this strategy to a specific Sonic validator.
* Only the registrator can call this function.
* @param validatorId the ID of the validator to delegate to
* @notice Delegate from this strategy to a specific Sonic validator. Called
* automatically on asset deposit
* @param amount the amount of Sonic (S) to delegate.
*/
function delegate(uint256 validatorId, uint256 amount)
external
onlyRegistrator
nonReentrant
{
require(isSupportedValidator(validatorId), "Validator not supported");
function _delegate(uint256 amount) internal {
require(
isSupportedValidator(defaultValidatorId),
"Validator not supported"
);
require(amount > 0, "Must delegate something");

// unwrap Wrapped Sonic (wS) to native Sonic (S)
IWrappedSonic(wrappedSonic).withdraw(amount);

ISFC(sfc).delegate{ value: amount }(validatorId);
ISFC(sfc).delegate{ value: amount }(defaultValidatorId);

emit Delegated(validatorId, amount);
emit Delegated(defaultValidatorId, amount);
}

function undelegate(uint256 validatorId, uint256 undelegateAmount)
external
onlyRegistrator
onlyRegistratorOrStrategist
nonReentrant
returns (uint256 withdrawId)
{
Expand Down Expand Up @@ -266,6 +278,16 @@ abstract contract SonicValidatorDelegator is InitializableAbstractStrategy {
emit RegistratorChanged(_address);
}

/// @notice Set the default validatorId to delegate to on deposit
function setDefaultValidatorId(uint256 validatorId)
external
onlyRegistratorOrStrategist
{
require(isSupportedValidator(validatorId), "Validator not supported");
defaultValidatorId = validatorId;
emit DefaultValidatorIdChanged(validatorId);
}

/// @notice Allows a validator to be delegated to by the Registrator
function supportValidator(uint256 validatorId) external onlyGovernor {
require(
Expand Down
7 changes: 6 additions & 1 deletion contracts/deploy/sonic/000_mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ const deployOracleRouter = async () => {
};

const deployCore = async () => {
const { governorAddr, deployerAddr } = await getNamedAccounts();
const { governorAddr, deployerAddr, strategistAddr } =
await getNamedAccounts();
const sGovernor = await ethers.provider.getSigner(governorAddr);
const sDeployer = await ethers.provider.getSigner(deployerAddr);

Expand Down Expand Up @@ -119,6 +120,10 @@ const deployCore = async () => {
await cOSonicVault.connect(sGovernor).unpauseCapital();
// Set withdrawal claim delay to 1 day
await cOSonicVault.connect(sGovernor).setWithdrawalClaimDelay(86400);

await withConfirmation(
cOSonicVault.connect(sGovernor).setStrategistAddr(strategistAddr)
);
};

const deployStakingStrategy = async () => {
Expand Down
36 changes: 22 additions & 14 deletions contracts/deploy/sonic/001_origin_sonic.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const {
deployWithConfirmation,
withConfirmation,
} = require("../../utils/deploy");
const { impersonateAndFund } = require("../../utils/signers");
const addresses = require("../../utils/addresses");

module.exports = deployOnSonic(
Expand All @@ -13,8 +14,11 @@ module.exports = deployOnSonic(
async ({ ethers }) => {
const { governorAddr, deployerAddr } = await getNamedAccounts();
console.log(`Governor: ${governorAddr}`);
console.log(`Governor: ${addresses.sonic.guardian}`);
console.log(`Deployer: ${deployerAddr}`);
const sGovernor = await ethers.provider.getSigner(governorAddr);
// TODO this needs to change in the actual deploy file
const sStrategist = await impersonateAndFund(addresses.sonic.guardian);
const sDeployer = await ethers.provider.getSigner(deployerAddr);

const cWS = await ethers.getContractAt("IWrappedSonic", addresses.sonic.wS);
Expand Down Expand Up @@ -172,20 +176,6 @@ module.exports = deployOnSonic(
);
console.log("Approved Sonic Staking Strategy on Vault");

// verify validators here: https://explorer.soniclabs.com/staking
for (const validatorId of [15, 16, 17, 18]) {
await cSonicStakingStrategy
.connect(sGovernor)
.supportValidator(validatorId);
}
console.log("Added supported validators");

// Set Defender Relayer for Sonic validator controls
await cSonicStakingStrategy
.connect(sGovernor)
.setRegistrator(addresses.sonic.validatorRegistrator);
console.log("Set registrator");

// Deploy the Dripper
await deployWithConfirmation("OSonicDripperProxy");

Expand Down Expand Up @@ -233,6 +223,24 @@ module.exports = deployOnSonic(
);
console.log("Configured Vault");

// verify validators here: https://explorer.soniclabs.com/staking
for (const validatorId of [15, 16, 17, 18]) {
await cSonicStakingStrategy
.connect(sGovernor)
.supportValidator(validatorId);
}

console.log("Added supported validators");

// Set Defender Relayer for Sonic validator controls
await cSonicStakingStrategy
.connect(sGovernor)
.setRegistrator(addresses.sonic.validatorRegistrator);
console.log("Set registrator");

await cSonicStakingStrategy.connect(sStrategist).setDefaultValidatorId(18);
console.log("Set the default validator id");

// Deploy the Zapper
await deployWithConfirmation("OSonicZapper", [
cOSonic.address,
Expand Down
Loading

0 comments on commit 19c60a7

Please sign in to comment.