Skip to content

Commit

Permalink
Fixed Sonic unit tests
Browse files Browse the repository at this point in the history
Prettier and linter
  • Loading branch information
naddison36 committed Jan 8, 2025
1 parent eebc293 commit 6f563aa
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 208 deletions.
69 changes: 69 additions & 0 deletions contracts/contracts/mocks/MockSFC.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./MintableERC20.sol";

contract MockSFC {
error ZeroAmount();
error TransferFailed();

// Mapping of delegator address to validator ID to amount delegated
mapping(address => mapping(uint256 => uint256)) public delegations;
// Mapping of delegator address to validator ID to withdrawal request ID to amount
mapping(address => mapping(uint256 => mapping(uint256 => uint256)))
public withdraws;

function getStake(address delegator, uint256 validatorID)
external
view
returns (uint256)
{
return delegations[delegator][validatorID];
}

function delegate(uint256 validatorID) external payable {
if (msg.value == 0) {
revert ZeroAmount();
}
delegations[msg.sender][validatorID] += msg.value;
}

function undelegate(
uint256 validatorID,
uint256 wrID,
uint256 amount
) external {
require(
delegations[msg.sender][validatorID] >= amount,
"insufficient stake"
);
require(
withdraws[msg.sender][validatorID][wrID] == 0,
"withdrawal request already exists"
);

delegations[msg.sender][validatorID] -= amount;
withdraws[msg.sender][validatorID][wrID] = amount;
}

function withdraw(uint256 validatorID, uint256 wrID) external {
require(withdraws[msg.sender][validatorID][wrID] > 0, "no withdrawal");

(bool sent, ) = msg.sender.call{
value: withdraws[msg.sender][validatorID][wrID]
}("");
if (!sent) {
revert TransferFailed();
}
}

function pendingRewards(address delegator, uint256 validatorID)
external
view
returns (uint256)
{}

function claimRewards(uint256 validatorID) external {}

function restakeRewards(uint256 validatorID) external {}
}
15 changes: 8 additions & 7 deletions contracts/contracts/strategies/sonic/SonicValidatorDelegator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import { IVault } from "../../interfaces/IVault.sol";
import { ISFC } from "../../interfaces/sonic/ISFC.sol";
import { IWrappedSonic } from "../../interfaces/sonic/IWrappedSonic.sol";

import "hardhat/console.sol";

/**
* @title Manages delegation to Sonic validators
* @notice This contract implements all the required functionality to delegate to, undelegate from and withdraw from validators.
* @notice This contract implements all the required functionality to delegate to,
undelegate from and withdraw from validators.
* @author Origin Protocol Inc
*/
abstract contract SonicValidatorDelegator is InitializableAbstractStrategy {
Expand Down Expand Up @@ -121,9 +120,11 @@ abstract contract SonicValidatorDelegator is InitializableAbstractStrategy {
// For each supported validator, get the staked amount and pending rewards
for (uint256 i = 0; i < supportedValidators.length; i++) {
// Get the staked amount and any pending rewards
balance +=
ISFC(sfc).getStake(address(this), supportedValidators[i]);
ISFC(sfc).pendingRewards(address(this), supportedValidators[i]);
balance += ISFC(sfc).getStake(
address(this),
supportedValidators[i]
);
ISFC(sfc).pendingRewards(address(this), supportedValidators[i]);
}
}

Expand Down Expand Up @@ -285,7 +286,7 @@ abstract contract SonicValidatorDelegator is InitializableAbstractStrategy {
}

/// @notice Returns the length of the supportedValidators array
function supportedValidatorsLength() external view returns(uint256) {
function supportedValidatorsLength() external view returns (uint256) {
return supportedValidators.length;
}

Expand Down
56 changes: 55 additions & 1 deletion contracts/deploy/sonic/000_mock.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
const { deployWithConfirmation } = require("../../utils/deploy");
const {
deployWithConfirmation,
withConfirmation,
} = require("../../utils/deploy");
const { isFork, isSonic, oethUnits } = require("../../test/helpers");

const deployMocks = async () => {
await deployWithConfirmation("MockWS", []);
await deployWithConfirmation("MockSFC", []);
};

const deployOracleRouter = async () => {
Expand Down Expand Up @@ -117,10 +121,60 @@ const deployCore = async () => {
await cOSonicVault.connect(sGovernor).unpauseCapital();
};

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

const cWS = await ethers.getContract("MockWS");
const cSFC = await ethers.getContract("MockSFC");

const cOSonicVaultProxy = await ethers.getContract("OSonicVaultProxy");

// Get contract instances
const cOSonicVault = await ethers.getContractAt(
"IVault",
cOSonicVaultProxy.address
);

// Staking Strategy
await deployWithConfirmation("SonicStakingStrategyProxy");

const cSonicStakingStrategyProxy = await ethers.getContract(
"SonicStakingStrategyProxy"
);
const dSonicStakingStrategy = await deployWithConfirmation(
"SonicStakingStrategy",
[
[cSFC.address, cOSonicVault.address], // platformAddress, VaultAddress
cWS.address,
cSFC.address,
]
);
const cSonicStakingStrategy = await ethers.getContractAt(
"SonicStakingStrategy",
cSonicStakingStrategyProxy.address
);

// Init the Sonic Staking Strategy
const initSonicStakingStrategy =
cSonicStakingStrategy.interface.encodeFunctionData("initialize()", []);
// prettier-ignore
await withConfirmation(
cSonicStakingStrategyProxy
.connect(sDeployer)["initialize(address,address,bytes)"](
dSonicStakingStrategy.address,
governorAddr,
initSonicStakingStrategy
)
);
console.log("Initialized SonicStakingStrategy proxy and implementation");
};

const main = async () => {
await deployMocks();
await deployOracleRouter();
await deployCore();
await deployStakingStrategy();
};

main.id = "000_mock";
Expand Down
23 changes: 15 additions & 8 deletions contracts/test/_fixture-sonic.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,13 @@ const defaultSonicFixture = deployments.createFixture(async () => {
);

// Sonic staking strategy
const sonicStakingStrategyProxy = await ethers.getContract("SonicStakingStrategyProxy");
const sonicStakingStrategy = await ethers.getContractAt("SonicStakingStrategy", sonicStakingStrategyProxy.address);
const sonicStakingStrategyProxy = await ethers.getContract(
"SonicStakingStrategyProxy"
);
const sonicStakingStrategy = await ethers.getContractAt(
"SonicStakingStrategy",
sonicStakingStrategyProxy.address
);

// let dripper, harvester;
// if (isFork) {
Expand Down Expand Up @@ -106,13 +111,15 @@ const defaultSonicFixture = deployments.createFixture(async () => {
);
const oSonicVaultSigner = await impersonateAndFund(oSonicVault.address);

let strategist, validatorRegistrator;
if (isFork) {
// Impersonate strategist on Fork
strategist = await impersonateAndFund(strategistAddr);
strategist.address = strategistAddr;
// Impersonate strategist
const strategist = await impersonateAndFund(strategistAddr);
strategist.address = strategistAddr;

validatorRegistrator = await impersonateAndFund(addresses.sonic.validatorRegistrator);
let validatorRegistrator;
if (isFork) {
validatorRegistrator = await impersonateAndFund(
addresses.sonic.validatorRegistrator
);
validatorRegistrator.address = addresses.sonic.validatorRegistrator;

await impersonateAndFund(governor.address);
Expand Down
52 changes: 22 additions & 30 deletions contracts/test/behaviour/sfcStakingStrategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ const { oethUnits } = require("../helpers");
const shouldBehaveLikeASFCStakingStrategy = (context) => {
describe("Initial setup", function () {
it("Should verify the initial state", async () => {
const { sonicStakingStrategy, addresses, oSonicVault, testValidatorIds } = await context();
const { sonicStakingStrategy, addresses, oSonicVault, testValidatorIds } =
await context();
expect(await sonicStakingStrategy.wrappedSonic()).to.equal(
addresses.wS,
"Incorrect wrapped sonic address set"
);

expect(await sonicStakingStrategy.sfc()).to.equal(
addresses.SFC,
"Incorrect SFC address set"
Expand All @@ -41,10 +42,9 @@ const shouldBehaveLikeASFCStakingStrategy = (context) => {
);

for (const validatorId of testValidatorIds) {
expect(await sonicStakingStrategy.isSupportedValidator(validatorId)).to.equal(
true,
"Validator expected to be supported"
);
expect(
await sonicStakingStrategy.isSupportedValidator(validatorId)
).to.equal(true, "Validator expected to be supported");
}

expect(await sonicStakingStrategy.platformAddress()).to.equal(
Expand All @@ -62,20 +62,18 @@ const shouldBehaveLikeASFCStakingStrategy = (context) => {
"Harvester address not empty"
);

expect((await sonicStakingStrategy.getRewardTokenAddresses()).length).to.equal(
0,
"Incorrectly configured Reward Token Addresses"
);
expect(
(await sonicStakingStrategy.getRewardTokenAddresses()).length
).to.equal(0, "Incorrectly configured Reward Token Addresses");
});
});

describe("Deposit/Delegation", function () {
const depositTokenAmount = async (depositAmount) => {
const { sonicStakingStrategy, oSonicVaultSigner, wS, clement } = await context();
const { sonicStakingStrategy, oSonicVaultSigner, wS, clement } =
await context();

const wsBalanceBefore = await wS.balanceOf(
sonicStakingStrategy.address
);
const wsBalanceBefore = await wS.balanceOf(sonicStakingStrategy.address);

const strategyBalanceBefore = await sonicStakingStrategy.checkBalance(
wS.address
Expand All @@ -99,9 +97,7 @@ const shouldBehaveLikeASFCStakingStrategy = (context) => {
wsBalanceBefore.add(depositAmount),
"WS not transferred"
);
expect(
await sonicStakingStrategy.checkBalance(wS.address)
).to.equal(
expect(await sonicStakingStrategy.checkBalance(wS.address)).to.equal(
strategyBalanceBefore.add(depositAmount),
"strategy checkBalance not increased"
);
Expand All @@ -117,17 +113,12 @@ const shouldBehaveLikeASFCStakingStrategy = (context) => {
).to.be.revertedWith("unsupported function");

await expect(
sonicStakingStrategy
.connect(governor)
.collectRewardTokens()
sonicStakingStrategy.connect(governor).collectRewardTokens()
).to.be.revertedWith("unsupported function");

await expect(
sonicStakingStrategy
.connect(governor)
.removePToken(wS.address)
sonicStakingStrategy.connect(governor).removePToken(wS.address)
).to.be.revertedWith("unsupported function");

});

it("Should accept and handle S token allocation", async () => {
Expand All @@ -136,7 +127,12 @@ const shouldBehaveLikeASFCStakingStrategy = (context) => {
});

it("Should accept and handle S token allocation and delegation to SFC", async () => {
const { sonicStakingStrategy, validatorRegistrator, testValidatorIds, wS } = await context();
const {
sonicStakingStrategy,
validatorRegistrator,
testValidatorIds,
wS,
} = await context();
const depositAmount = oethUnits("15000");

await depositTokenAmount(depositAmount);
Expand All @@ -150,15 +146,11 @@ const shouldBehaveLikeASFCStakingStrategy = (context) => {
.withArgs(testValidatorIds[0], depositAmount);

// checkBalance should account for the full amount delegated to the validator
expect(
await sonicStakingStrategy.checkBalance(wS.address)
).to.equal(
expect(await sonicStakingStrategy.checkBalance(wS.address)).to.equal(
depositAmount,
"Strategy checkBalance not expected"
);
});


});
};

Expand Down
9 changes: 4 additions & 5 deletions contracts/test/strategies/sonicStaking.sonic.fork-test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const { defaultSonicFixture } = require("./../_fixture-sonic");
const { shouldBehaveLikeASFCStakingStrategy } = require("../behaviour/sfcStakingStrategy");
const {
shouldBehaveLikeASFCStakingStrategy,
} = require("../behaviour/sfcStakingStrategy");
const addresses = require("../../utils/addresses");

describe("Sonic ForkTest: Sonic Staking Strategy", function () {
Expand All @@ -14,10 +16,7 @@ describe("Sonic ForkTest: Sonic Staking Strategy", function () {
return {
...fixture,
addresses: addresses.sonic,
sfcAddress: await ethers.getContractAt(
"ISFC",
addresses.sonic.SFC
),
sfcAddress: await ethers.getContractAt("ISFC", addresses.sonic.SFC),
// see validators here: https://explorer.soniclabs.com/staking
testValidatorIds: [15, 16, 17, 18],
};
Expand Down
Loading

0 comments on commit 6f563aa

Please sign in to comment.