Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Staking and CCIP transition to USDC #488

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions contracts/EscrowAndStaking/StakingThales.sol
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,11 @@ contract StakingThales is IStakingThales, Initializable, ProxyOwned, ProxyReentr
emit StakingRewardsParametersChanged(_fixedReward, _extraReward, _extraRewardsActive);
}

function setFeeToken(address _feeToken) external onlyOwner {
require(paused, "Contract must be paused");
feeToken = IERC20(_feeToken);
}

/// @notice Set contract addresses
/// @param _thalesAMM address of Thales AMM contract
/// @param _thalesRangedAMM address of Thales ranged AMM contract
Expand Down
15 changes: 15 additions & 0 deletions scripts/abi/StakingThales.json
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,21 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "_feeToken",
"type": "address"
}
],
"name": "setFeeToken",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
Expand Down
234 changes: 234 additions & 0 deletions test/contracts/Staking/CCIP2_StakingThales.js
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,240 @@ contract('StakingThales', (accounts) => {
await StakingThalesDeployed.claimReward({ from: first });
});

it('Pause contract, change fee token to USDC, add USDC, unpause and close period', async () => {
// Deploy USDC token (6 decimals)

// Initial setup
let deposit = toUnit(100000);
let stake = toUnit(1500);
await ThalesDeployed.transfer(first, stake, { from: owner });
await StakingThalesDeployed.setStakingRewardsParameters(deposit, 100000, false, {
from: owner,
});
await EscrowThalesDeployed.setStakingThalesContract(StakingThalesDeployed.address, {
from: owner,
});
let answer = await StakingThalesDeployed.getContractFeeFunds();
assert.bnEqual(answer, 0);
await expect(StakingThalesDeployed.closePeriod({ from: first })).to.be.revertedWith(
'Staking period has not started'
);
await ThalesDeployed.transfer(ThalesStakingRewardsPoolDeployed.address, toUnit(200000), {
from: owner,
});
await StakingThalesDeployed.startStakingPeriod({ from: owner });
await ThalesDeployed.approve(StakingThalesDeployed.address, stake, { from: first });
await StakingThalesDeployed.stake(stake, { from: first });
await fastForward(WEEK + SECOND);
await StakingThalesDeployed.closePeriod({ from: second });
answer = await StakingThalesDeployed.getRewardsAvailable(first);
// Check if feeToken is equal to sUSDSynth address
const feeToken = await StakingThalesDeployed.feeToken();
assert.equal(feeToken, sUSDSynth.address);
await StakingThalesDeployed.claimReward({ from: first });

// Pause the StakingThales contract
await StakingThalesDeployed.setPaused(true, { from: owner });

// Add USDC to the staking contract (let's say 1000 USDC)
const amountSixDecimal = 1000 * 1e6; // 1000 USDC with 6 decimals
await ThalesSixDecimal.transfer(StakingThalesDeployed.address, amountSixDecimal, {
from: owner,
});
// Change fee token to USDC
await StakingThalesDeployed.setFeeToken(ThalesSixDecimal.address, { from: owner });

// Unpause the contract
await StakingThalesDeployed.setPaused(false, { from: owner });
await fastForward(WEEK + SECOND);
// Close the period
await StakingThalesDeployed.closePeriod({ from: owner });

// Check if the distribution is correct
const totalStaked = await StakingThalesDeployed.totalStakedLastPeriodEnd();
const totalEscrowed = await StakingThalesDeployed.totalEscrowedLastPeriodEnd();
const totalStakedAndEscrowed = totalStaked.add(totalEscrowed);

console.log(fromUnit(totalStaked), fromUnit(totalEscrowed), fromUnit(totalStakedAndEscrowed));
const stakedBalance = await StakingThalesDeployed.stakedBalanceOf(first);
const escrowedBalance = await EscrowThalesDeployed.getStakedEscrowedBalanceForRewards(first);
const totalBalance = stakedBalance.add(escrowedBalance);

const actualReward = await StakingThalesDeployed.getRewardFeesAvailable(first);

// Only Staker should be able to claim the full amount
assert.equal(fromUnit(actualReward), fromUnit(amountSixDecimal.toString()));

// Claim rewards and verify
const balanceBeforeClaim = await ThalesSixDecimal.balanceOf(first);
await StakingThalesDeployed.claimReward({ from: first });
const balanceAfterClaim = await ThalesSixDecimal.balanceOf(first);
const claimedAmount = balanceAfterClaim.sub(balanceBeforeClaim);
console.log('actualReward', fromUnit(actualReward));
console.log('claimedAmount', fromUnit(claimedAmount));

assert.equal(fromUnit(actualReward), fromUnit(claimedAmount));
});

it('Stake with first, claim reward, activate CCIP, close period, change fee token to USDC, add USDC, unpause and close period, claim Rewards', async () => {
let deposit = toUnit(100000);
let stake = toUnit(1500);
await ThalesDeployed.transfer(first, stake, { from: owner });
await StakingThalesDeployed.setStakingRewardsParameters(deposit, 100000, false, {
from: owner,
});
await EscrowThalesDeployed.setStakingThalesContract(StakingThalesDeployed.address, {
from: owner,
});
let answer = await StakingThalesDeployed.getContractFeeFunds();
assert.bnEqual(answer, 0);
await expect(StakingThalesDeployed.closePeriod({ from: first })).to.be.revertedWith(
'Staking period has not started'
);
await ThalesDeployed.transfer(ThalesStakingRewardsPoolDeployed.address, toUnit(200000), {
from: owner,
});
await StakingThalesDeployed.startStakingPeriod({ from: owner });
await ThalesDeployed.approve(StakingThalesDeployed.address, stake, { from: first });
await StakingThalesDeployed.stake(stake, { from: first });
await fastForward(WEEK + SECOND);
await StakingThalesDeployed.closePeriod({ from: second });
answer = await StakingThalesDeployed.getRewardsAvailable(first);
await StakingThalesDeployed.claimReward({ from: first });
await fastForward(WEEK + SECOND);
await StakingThalesDeployed.closePeriod({ from: second });
let answer2 = await EscrowThalesDeployed.getStakedEscrowedBalanceForRewards(first);
assert.bnEqual(answer, answer2);
await AddressManager.setAddressInAddressBook('CrossChainCollector', CCIPCollector.address, {
from: owner,
});
await AddressManager.setAddressInAddressBook('SafeBoxBuffer', SafeBoxBuffer.address, {
from: owner,
});
await fastForward(WEEK + SECOND);
await StakingThalesDeployed.closePeriod({ from: second });
await sUSDSynth.transfer(StakingThalesDeployed.address, 1001, { from: initialCreator });
let closingPeriodInProgress = await StakingThalesDeployed.closingPeriodInProgress();
assert.equal(closingPeriodInProgress, true);
assert.equal(await StakingThalesDeployed.paused(), true);
await expect(StakingThalesDeployed.claimReward({ from: first })).to.be.revertedWith(
'This action cannot be performed while the contract is paused'
);
await AddressManager.setAddressInAddressBook('CrossChainCollector', second, {
from: owner,
});
await AddressManager.setAddressInAddressBook('StakingThales', StakingThalesDeployed.address, {
from: owner,
});
// await StakingThalesDeployed.setCrossChainCollector(second, SafeBoxBuffer.address, {
// from: owner,
// });
let paused = await StakingThalesDeployed.paused();
assert.equal(paused, true);
let totalStaked = await StakingThalesDeployed.totalStakedLastPeriodEnd();
let totalEscrowed = await StakingThalesDeployed.totalEscrowedLastPeriodEnd();
await StakingThalesDeployed.setStakingRewardsParameters(toUnit(1000000), 100000, false, {
from: owner,
});
await StakingThalesDeployed.updateStakingRewards(toUnit(1000000), 1000000, 1000, {
from: second,
});
let availableRewards = await StakingThalesDeployed.getRewardsAvailable(first);
assert.equal(fromUnit(availableRewards), 1000000);
await expect(StakingThalesDeployed.claimReward({ from: first })).to.be.revertedWith(
'revert SafeERC20: low-level call failed'
);
await ThalesDeployed.transfer(ThalesStakingRewardsPoolDeployed.address, toUnit(1000000), {
from: owner,
});

const feeToken = await StakingThalesDeployed.feeToken();
assert.equal(feeToken, sUSDSynth.address);
await StakingThalesDeployed.claimReward({ from: first });

// Pause the StakingThales contract
await StakingThalesDeployed.setPaused(true, { from: owner });

// Add USDC to the staking contract (let's say 1000 USDC)
const amountSixDecimal = 1000 * 1e6; // 1000 USDC with 6 decimals
const amountSixDecimalToBuffer = 2000 * 1e6; // 1000 USDC with 6 decimals
await ThalesSixDecimal.transfer(StakingThalesDeployed.address, amountSixDecimal, {
from: owner,
});
await ThalesSixDecimal.transfer(SafeBoxBuffer.address, amountSixDecimalToBuffer, {
from: owner,
});
// Change fee token to USDC
await StakingThalesDeployed.setFeeToken(ThalesSixDecimal.address, { from: owner });
await SafeBoxBuffer.setAddressManager(AddressManager.address, { from: owner });
await SafeBoxBuffer.setSUSD(ThalesSixDecimal.address, { from: owner });
let sUSDAddress = await SafeBoxBuffer.sUSD();
assert.equal(sUSDAddress, ThalesSixDecimal.address);
await AddressManager.setAddressInAddressBook('CrossChainCollector', CCIPCollector.address, {
from: owner,
});

let newFeeToken = await StakingThalesDeployed.feeToken();
assert.equal(newFeeToken, ThalesSixDecimal.address);
// Unpause the contract
await StakingThalesDeployed.setPaused(false, { from: owner });
await fastForward(WEEK + 5 * SECOND);
closingPeriodInProgress = await StakingThalesDeployed.closingPeriodInProgress();
assert.equal(closingPeriodInProgress, false);
let balance = await ThalesSixDecimal.balanceOf(StakingThalesDeployed.address);
assert.equal(balance.toString(), amountSixDecimal.toString());

let canClosePeriod = await StakingThalesDeployed.canClosePeriod();
assert.equal(canClosePeriod, true);
// Close the period
await fastForward(2 * SECOND);
await StakingThalesDeployed.closePeriod({ from: second });
await AddressManager.setAddressInAddressBook('CrossChainCollector', second, {
from: owner,
});
let newAmount = 1500 * 1e6;
let newAmountTransformed = toUnit(1500);
console.log('newAmountTransformed', newAmountTransformed);
await StakingThalesDeployed.updateStakingRewards(
toUnit(1000000),
1000000,
newAmountTransformed,
{
from: second,
}
);
// Check if the distribution is correct
totalStaked = await StakingThalesDeployed.totalStakedLastPeriodEnd();
totalEscrowed = await StakingThalesDeployed.totalEscrowedLastPeriodEnd();
const totalStakedAndEscrowed = totalStaked.add(totalEscrowed);

console.log(fromUnit(totalStaked), fromUnit(totalEscrowed), fromUnit(totalStakedAndEscrowed));
const stakedBalance = await StakingThalesDeployed.stakedBalanceOf(first);
const escrowedBalance = await EscrowThalesDeployed.getStakedEscrowedBalanceForRewards(first);
const totalBalance = stakedBalance.add(escrowedBalance);

const actualReward = await StakingThalesDeployed.getRewardFeesAvailable(first);

// Only Staker should be able to claim the full amount
assert.equal(fromUnit(actualReward), fromUnit(newAmount.toString()));

// Claim rewards and verify
const balanceBeforeClaim = await ThalesSixDecimal.balanceOf(first);
await expect(StakingThalesDeployed.claimReward({ from: first })).to.be.revertedWith(
'revert SafeERC20: low-level call failed'
);
await ThalesDeployed.transfer(ThalesStakingRewardsPoolDeployed.address, toUnit(1000000), {
from: owner,
});
await StakingThalesDeployed.claimReward({ from: first });
const balanceAfterClaim = await ThalesSixDecimal.balanceOf(first);
const claimedAmount = balanceAfterClaim.sub(balanceBeforeClaim);
console.log('actualReward', fromUnit(actualReward));
console.log('claimedAmount', fromUnit(claimedAmount));

assert.equal(fromUnit(actualReward), fromUnit(claimedAmount));
});

it('Stake with first account and claim reward', async () => {
let deposit = toUnit(100000);
let stake = toUnit(1500);
Expand Down