Skip to content

Commit

Permalink
SFS: staking rewards & swap
Browse files Browse the repository at this point in the history
  • Loading branch information
tempe-techie committed Jan 29, 2024
1 parent e978dfe commit 88218a5
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 78 deletions.
58 changes: 0 additions & 58 deletions contracts/post/IggyPostNft721.sol

This file was deleted.

10 changes: 9 additions & 1 deletion contracts/staking/IggyStakingRewards.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.s
import { OwnableWithManagers } from "../access/OwnableWithManagers.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";

interface ISFS {
function assign(uint256 _tokenId) external returns (uint256);
}

/**
@title Staking contract with periodic ETH rewards (with voting and permit)
@author Tempe Techie
Expand Down Expand Up @@ -62,14 +66,18 @@ contract IggyStakingRewards is ERC20, OwnableWithManagers, ReentrancyGuard, ERC2
string memory _receiptTokenSymbol,
uint256 _claimRewardsMinimum,
uint256 _minDeposit,
uint256 _periodLength
uint256 _periodLength,
address _sfsAddress,
uint256 _tokenId
) ERC20(_receiptTokenName, _receiptTokenSymbol) ERC20Permit(_receiptTokenName) {
require(_asset != address(0), "PeriodicEthRewards: asset is the zero address");
require(_weth != address(0), "PeriodicEthRewards: weth is the zero address");
require(_periodLength > 0, "PeriodicEthRewards: period length is zero");
require(bytes(_receiptTokenName).length > 0, "PeriodicEthRewards: receipt token name is empty");
require(bytes(_receiptTokenSymbol).length > 0, "PeriodicEthRewards: receipt token symbol is empty");

ISFS(_sfsAddress).assign(_tokenId);

asset = _asset;
weth = _weth;

Expand Down
8 changes: 8 additions & 0 deletions contracts/swap/IggySwapRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { OwnableWithManagers } from "../access/OwnableWithManagers.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

interface ISFS {
function assign(uint256 _tokenId) external returns (uint256);
}

interface IStats {
function addWeiSpent(address user_, uint256 weiSpent_) external;
}
Expand Down Expand Up @@ -110,10 +114,14 @@ contract IggySwapRouter is OwnableWithManagers {
address _routerAddress,
address _stakingAddress,
address _statsAddress,
address _sfsAddress,
uint256 _sfsNftId,
uint256 _swapFee,
uint256 _stakingShare,
uint256 _frontendShare
) {
ISFS(_sfsAddress).assign(_sfsNftId);

frontendAddress = _frontendAddress;
iggyAddress = _iggyAddress;
routerAddress = _routerAddress;
Expand Down
8 changes: 8 additions & 0 deletions contracts/swap/IggySwapRouterSolidly.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { OwnableWithManagers } from "../access/OwnableWithManagers.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

interface ISFS {
function assign(uint256 _tokenId) external returns (uint256);
}

interface IStats {
function addWeiSpent(address user_, uint256 weiSpent_) external;
}
Expand Down Expand Up @@ -117,10 +121,14 @@ contract IggySwapRouterSolidly is OwnableWithManagers {
address _stakingAddress,
address _statsAddress,
address _wethAddress,
address _sfsAddress,
uint256 _sfsNftId,
uint256 _swapFee,
uint256 _stakingShare,
uint256 _frontendShare
) {
ISFS(_sfsAddress).assign(_sfsNftId); // assign SFS NFT to this contract

frontendAddress = _frontendAddress;
iggyAddress = _iggyAddress;
routerAddress = _routerAddress;
Expand Down
32 changes: 24 additions & 8 deletions scripts/staking/iggyStakingRewards.deploy.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
// npx hardhat run scripts/staking/iggyStakingRewards.deploy.js --network modeTestnet
const contractName = "IggyStakingRewards";

const assetAddress = "0xF874f79eBfB8FEe898a289C4cAa5dc4383873431"; // token to stake
const wethAddress = "0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889"; // wrapped native coin (WETH, WSGB, WBNB, etc.)
const tokenName = "Iggy Governance Token";
const symbol = "IGT";
const claimRewardsMinimum = ethers.utils.parseEther("0.001"); // 10 SGB/ETH minimum total reward for a given week (if not met, rewards are rolled over to the next week)
const minDeposit = ethers.utils.parseEther("0.001"); // 0.001 LP tokens minimum deposit to stake
const assetAddress = ""; // token to stake
const wethAddress = ""; // wrapped native coin (WETH)
const tokenName = "ModeChat Governance Token";
const symbol = "MCG";
const claimRewardsMinimum = ethers.utils.parseEther("0.001"); // minimum total reward for a given week (if not met, rewards are rolled over to the next week)
const minDeposit = 1; // 1 wei LP tokens minimum deposit to stake
const periodLength = 604800; // 7 days

const sfsAddress = (network.name == "modeTestnet") ? "0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6" : "0x8680CEaBcb9b56913c519c069Add6Bc3494B7020";
const sfsNftTokenId = 0; // TODO: Enter SFS NFT token ID!!!

if (sfsNftTokenId == 0) {
console.log("Please enter SFS NFT token ID!!!");
return;
}

async function main() {
const [deployer] = await ethers.getSigners();

Expand All @@ -18,13 +26,21 @@ async function main() {
// deploy contract
const contract = await ethers.getContractFactory(contractName);
const instance = await contract.deploy(
assetAddress, wethAddress, tokenName, symbol, claimRewardsMinimum, minDeposit, periodLength
assetAddress,
wethAddress,
tokenName,
symbol,
claimRewardsMinimum,
minDeposit,
periodLength,
sfsAddress,
sfsNftTokenId
);

console.log(contractName + " contract address:", instance.address);

console.log("Wait a minute and then run this command to verify contracts on block explorer:");
console.log("npx hardhat verify --network " + network.name + " " + instance.address + " " + assetAddress + " " + wethAddress + ' "' + tokenName + '" "' + symbol + '" "' + claimRewardsMinimum + '" "' + minDeposit + '" "' + periodLength + '"');
console.log("npx hardhat verify --network " + network.name + " " + instance.address + " " + assetAddress + " " + wethAddress + ' "' + tokenName + '" "' + symbol + '" "' + claimRewardsMinimum + '" "' + minDeposit + '" "' + periodLength + '" ' + sfsAddress + ' "' + sfsNftTokenId + '"');
}

main()
Expand Down
18 changes: 14 additions & 4 deletions scripts/swap/IggySwapRouter.deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@

const contractName = "IggySwapRouter";

const iggyAddress = "0x6771F33Cfd8C6FC0A1766331f715f5d2E1d4E0e2"; // mandatory
const routerAddress = "0xE4f7776c753aF46D2aa23e3348d17548C86DC47D"; // mandatory
const iggyAddress = ""; // mandatory
const routerAddress = ""; // mandatory
const frontendAddress = ethers.constants.AddressZero; // optional
const stakingAddress = ethers.constants.AddressZero; // optional
const statsAddress = ethers.constants.AddressZero; // stats middleware address (optional)
const statsAddress = ""; // stats middleware address (optional)

const swapFee = 80; // 0.8%
const stakingShare = 4000; // bps
const frontendShare = 4000; // bps

const sfsAddress = (network.name == "modeTestnet") ? "0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6" : "0x8680CEaBcb9b56913c519c069Add6Bc3494B7020";
const sfsNftTokenId = 0; // TODO: Enter SFS NFT token ID!!!

if (sfsNftTokenId == 0) {
console.log("Please enter SFS NFT token ID!!!");
return;
}

async function main() {
const [deployer] = await ethers.getSigners();

Expand All @@ -26,6 +34,8 @@ async function main() {
routerAddress,
stakingAddress,
statsAddress,
sfsAddress,
sfsNftTokenId,
swapFee,
stakingShare,
frontendShare
Expand All @@ -48,7 +58,7 @@ async function main() {
console.log("Wait a minute and then run this command to verify contracts on block explorer:");
console.log(
"npx hardhat verify --network " + network.name + " " + instance.address + " " + frontendAddress + " " +
iggyAddress + " " + routerAddress + " " + stakingAddress + " " + statsAddress + ' "' + swapFee + '" "' + stakingShare + '" "' + frontendShare + '"'
iggyAddress + " " + routerAddress + " " + stakingAddress + " " + statsAddress + " " + sfsAddress + ' "' + sfsNftTokenId + '" "' + swapFee + '" "' + stakingShare + '" "' + frontendShare + '"'
);
}

Expand Down
22 changes: 16 additions & 6 deletions scripts/swap/IggySwapRouterSolidly.deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@

const contractName = "IggySwapRouterSolidly";

const frontendAddress = "0x6771F33Cfd8C6FC0A1766331f715f5d2E1d4E0e2";
const iggyAddress = "0x6771F33Cfd8C6FC0A1766331f715f5d2E1d4E0e2";
const routerAddress = "0xE11b93B61f6291d35c5a2beA0A9fF169080160cF";
const stakingAddress = "0x0000000000000000000000000000000000000000"; // zero address
const frontendAddress = "";
const iggyAddress = "";
const routerAddress = "";
const stakingAddress = ethers.constants.AddressZero; // zero address
const statsAddress = ""; // stats middleware address
const wethAddress = "0x4200000000000000000000000000000000000006";
const wethAddress = "";

const swapFee = 80; // 0.8%
const stakingShare = 0; // 80%
const frontendShare = 5000; // 50% of what's left after staking share and referral share are taken out

const sfsAddress = (network.name == "modeTestnet") ? "0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6" : "0x8680CEaBcb9b56913c519c069Add6Bc3494B7020";
const sfsNftTokenId = 0; // TODO: Enter SFS NFT token ID!!!

if (sfsNftTokenId == 0) {
console.log("Please enter SFS NFT token ID!!!");
return;
}

async function main() {
const [deployer] = await ethers.getSigners();

Expand All @@ -28,6 +36,8 @@ async function main() {
stakingAddress,
statsAddress,
wethAddress,
sfsAddress,
sfsNftTokenId,
swapFee,
stakingShare,
frontendShare
Expand All @@ -48,7 +58,7 @@ async function main() {
console.log("Wait a minute and then run this command to verify contracts on block explorer:");
console.log(
"npx hardhat verify --network " + network.name + " " + instance.address + " " + frontendAddress + " " +
iggyAddress + " " + routerAddress + " " + stakingAddress + " " + statsAddress + " " + wethAddress + ' "' + swapFee + '" "' + stakingShare + '" "' + frontendShare + '"'
iggyAddress + " " + routerAddress + " " + stakingAddress + " " + statsAddress + " " + wethAddress + " " + sfsAddress + ' "' + sfsNftTokenId + '" "' + swapFee + '" "' + stakingShare + '" "' + frontendShare + '"'
);
}

Expand Down
14 changes: 13 additions & 1 deletion test/swap/iggySwap.polygon.fork.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// test on a forked mainnet (polygon)
// 1. First run the forked localhost node: npx hardhat node --fork https://rpc.ankr.com/polygon // must be Polygon Mainnet
// 1. First run the forked localhost node: npx hardhat node --fork https://mainnet.mode.network // must be Mode testnet or mainnet
// 2. Then run the tests in a different tab: npx hardhat test test/swap/iggySwap.polygon.fork.test.js --network localhost

const { expect } = require("chai");
Expand Down Expand Up @@ -43,6 +43,14 @@ xdescribe("Iggy Swap tests (on a forked mainnet)", function () {
beforeEach(async function () {
[owner, frontend, iggy, user1, user2, referrer, staking] = await ethers.getSigners();

const MockSFS = await ethers.getContractFactory("MockSFS");
const sfsContract = await MockSFS.deploy();

const SfsNftInitialize = await ethers.getContractFactory("SfsNftInitialize");
const sfsNftInitializeContract = await SfsNftInitialize.deploy(sfsContract.address, referrer.address);

const sfsNftTokenId = await sfsNftInitializeContract.sfsNftTokenId();

// deploy IggySwapRouter
const IggySwapRouter = await ethers.getContractFactory("IggySwapRouter");
iggySwapRouterContract = await IggySwapRouter.deploy(
Expand All @@ -51,6 +59,8 @@ xdescribe("Iggy Swap tests (on a forked mainnet)", function () {
routerAddress,
staking.address,
ethers.constants.AddressZero,
sfsContract.address,
sfsNftTokenId,
swapFee,
stakingShare,
frontendShare
Expand All @@ -66,6 +76,8 @@ xdescribe("Iggy Swap tests (on a forked mainnet)", function () {
console.log("Owner's MATIC balance before swap:", ethers.utils.formatUnits(ownerEthBalanceBefore, "ether"), "MATIC");
expect(ownerEthBalanceBefore).to.be.gt(ethers.utils.parseUnits("9990", "ether"));

return;

// check frontend's DAI balance before swap
const daiContract = await ethers.getContractAt("@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20", daiAddress);
const frontendDaiBalanceBefore = await daiContract.balanceOf(frontend.address);
Expand Down

0 comments on commit 88218a5

Please sign in to comment.