Skip to content

Commit

Permalink
chore: Added script for deployment and interaction scripts (#2)
Browse files Browse the repository at this point in the history
* chore: Added script for deployment and interaction scripts

* chore: Added creation of temporary .env file for git actions to pass

* chore: Testet incentive creation and endIncentive scripts

* chore: Added prettier write command

* chore: Hardhat config fix

* chore: Added env.example

* chore: Scripts improvement

* chore: Ran prettier

* chore: Removed unneccesary part for script

* chore: Fixed typo
  • Loading branch information
tkemi authored Oct 14, 2024
1 parent 19bfff7 commit e1513ff
Show file tree
Hide file tree
Showing 14 changed files with 373 additions and 35 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PK=
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ artifacts/contracts/DragonswapV2Staker.sol/DragonswapV2Staker.dbg.json
artifacts/contracts/interfaces/**/*.dbg.json
!artifacts/contracts/libraries
artifacts/contracts/libraries/**/*.dbg.json

# env
.env
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12
12
31 changes: 31 additions & 0 deletions config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export default {
dragonswapV2Staker: {
mainnet: "0x72c0cd98d21ee3263D375437b4FDAC097b596dD6",
testnet: "",
},
refundee: {
mainnet: "",
testnet: "",
},
pool: {
mainnet: "",
testnet: "",
},
rewardToken: {
mainnet: "",
testnet: "",
},
startTime: {
mainnet: 0,
testnet: 0,
},
endTime: {
mainnet: 0,
testnet: 0,
},
rewardAmount: {
mainnet: 0, // Amount is converted to decimals of the reward token in the script
testnet: 0,
},
};

21 changes: 21 additions & 0 deletions contracts/mocks/Token.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

import '@openzeppelin/contracts/token/ERC20/ERC20.sol';

contract Token is ERC20 {
uint8 private tokenDecimals;

constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) ERC20(_name, _symbol) {
tokenDecimals = uint8(_decimals);
_mint(msg.sender, 100_000_000 * 10**_decimals);
}

function decimals() public view virtual override returns (uint8) {
return tokenDecimals;
}
}
Empty file added deployments/addresses.json
Empty file.
Empty file added deployments/incentives.json
Empty file.
52 changes: 18 additions & 34 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import '@nomiclabs/hardhat-waffle'
import '@typechain/hardhat'
import 'hardhat-contract-sizer'
import { HardhatUserConfig } from 'hardhat/config'
import { SolcUserConfig } from 'hardhat/types'
import { SolcUserConfig, NetworkUserConfig } from 'hardhat/types'
import 'solidity-coverage'
import "dotenv/config";

const accounts = process.env.PK ? [process.env.PK] : [];

const DEFAULT_COMPILER_SETTINGS: SolcUserConfig = {
version: '0.7.6',
Expand Down Expand Up @@ -35,44 +38,25 @@ if (process.env.RUN_COVERAGE == '1') {
}
}

const seiTestnet: NetworkUserConfig = {
url: "https://evm-rpc-testnet.sei-apis.com",
chainId: 1328,
accounts: accounts,
};

const seiMainnet: NetworkUserConfig = {
url: "https://evm-rpc.sei-apis.com",
chainId: 1329,
accounts: accounts,
};

const config: HardhatUserConfig = {
networks: {
hardhat: {
allowUnlimitedContractSize: false,
},
mainnet: {
url: `https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
ropsten: {
url: `https://ropsten.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
rinkeby: {
url: `https://rinkeby.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
goerli: {
url: `https://goerli.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
kovan: {
url: `https://kovan.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
arbitrumRinkeby: {
url: `https://arbitrum-rinkeby.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
arbitrum: {
url: `https://arbitrum-mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
optimismKovan: {
url: `https://optimism-kovan.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
optimism: {
url: `https://optimism-mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
mumbai: {
url: `https://polygon-mumbai.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
polygon: {
url: `https://polygon-mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`,
},
mainnet: seiMainnet,
testnet: seiTestnet,
},
solidity: {
compilers: [DEFAULT_COMPILER_SETTINGS],
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"compile": "hardhat compile",
"lint": "eslint . --ext .ts",
"prettier:check": "prettier-check contracts/**/*.sol test/**/*.ts types/*.ts",
"prettier:write": "prettier --write contracts/**/*.sol test/**/*.ts types/*.ts",
"size-contracts": "hardhat compile && hardhat size-contracts",
"test": "hardhat test",
"clear-cache": "rm -rf artifacts/ cache/ typechain/",
Expand Down
95 changes: 95 additions & 0 deletions scripts/createIncentive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { ethers, network, run } from "hardhat";
import config from "../config";
import { saveJson, jsons, sleep } from "./utils";
import { parseUnits } from "ethers/lib/utils";

const wait = async () => {
await sleep(3000);
};

const main = async () => {
// Get network data from Hardhat config (see hardhat.config.ts).
const networkName = network.name;

// Check if the network is supported.
if (networkName === "testnet" || networkName === "mainnet") {
console.log(`Creating incentive on ${networkName} network...`);

const zeroAddress = ethers.constants.AddressZero;
const refundeeAddress = config.refundee[networkName];

// Check if the addresses in the config are set.
if (refundeeAddress === zeroAddress || refundeeAddress === null || refundeeAddress === "") {
throw new Error("Missing refundee address");
}

// Compile contracts.
await run("compile");
console.log("Compiled contracts...");

const dragonswapV2StakerAddress = config.dragonswapV2Staker[networkName];

const dragonswapV2Staker = await ethers.getContractAt(
"DragonswapV2Staker",
dragonswapV2StakerAddress,
);

// Define incentive parameters
const rewardToken = config.rewardToken[networkName]; // Address of the reward token
const pool = config.pool[networkName]; // Address of the Dragonswap V2 pool
const startTime = config.startTime[networkName]; // Start time
const endTime = config.endTime[networkName]; // End time
const refundee = refundeeAddress; // Address to receive leftover rewards

// Create the incentive key
const incentiveKey = {
rewardToken,
pool,
startTime,
endTime,
refundee
};

// Approve the DragonswapV2Staker contract to spend reward tokens
const rewardTokenContract = await ethers.getContractAt("Token", rewardToken);
const rewardTokenDecimals = await rewardTokenContract.decimals();
const rewardAmount = parseUnits(config.rewardAmount[networkName].toString(), rewardTokenDecimals);
await rewardTokenContract.approve(dragonswapV2StakerAddress, rewardAmount);

await wait();

// Create the incentive
const createIncentiveTx = await dragonswapV2Staker.createIncentive(
incentiveKey,
rewardAmount
);

const createIncentiveTxReceipt = await createIncentiveTx.wait();

console.log("Incentive created. Transaction hash:", createIncentiveTxReceipt.transactionHash);

// Save the incentive details
saveJson(
jsons.incentives,
network.name,
"latestIncentive",
{
rewardToken,
pool,
startTime,
endTime,
refundee,
rewardAmount: rewardAmount.toString()
}
);
} else {
console.log(`Creating incentive on ${networkName} network is not supported...`);
}
};

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
31 changes: 31 additions & 0 deletions scripts/deployMockToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { saveJson, jsons } from './utils';
import { ethers , network, run } from "hardhat";


async function main() {
// Compile contracts.
await run("compile");
console.log("Compiled contracts...");

const name = "MockToken";
const symbol = "MTKN";
const decimals = 6;

const mockTokenFactory = await ethers.getContractFactory('Token');
const mockToken = await mockTokenFactory.deploy(name, symbol, decimals);
await mockToken.deployed();
console.log(`MockToken address: ${mockToken.address}`);

saveJson(jsons.addresses, network.name, 'MockToken', mockToken.address);

console.log('Done!');
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
64 changes: 64 additions & 0 deletions scripts/endIncentiveFromConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { ethers, network, run } from "hardhat";
import config from "../config";
import { jsons, sleep, getJson } from "./utils";

const wait = async () => {
await sleep(3000);
};

const main = async () => {
// Get network data from Hardhat config
const networkName = network.name;

// Check if the network is supported
if (networkName === "testnet" || networkName === "mainnet") {
console.log(`Ending incentive on ${networkName} network...`);

// Compile contracts
await run("compile");
console.log("Compiled contracts...");

const dragonswapV2StakerAddress = config.dragonswapV2Staker[networkName];

const dragonswapV2Staker = await ethers.getContractAt(
"DragonswapV2Staker",
dragonswapV2StakerAddress,
);

// Load the incentive to end details from config
const incentiveFromConfig = {
rewardToken: config.rewardToken[networkName],
pool: config.pool[networkName],
startTime: config.startTime[networkName],
endTime: config.endTime[networkName],
refundee: config.refundee[networkName]
};

await wait();
// End the incentive
const endIncentiveTx = await dragonswapV2Staker.endIncentive(incentiveFromConfig);

const endIncentiveTxReceipt = await endIncentiveTx.wait();

console.log("Incentive ended. Transaction hash:", endIncentiveTxReceipt.transactionHash);

// Get the refund amount from the transaction logs
const refundEvent = endIncentiveTxReceipt.events?.find(e => e.event === "IncentiveEnded");
const refundAmount = refundEvent?.args?.refund;

const rewardTokenContract = await ethers.getContractAt("Token", incentiveFromConfig.rewardToken);
const rewardTokenDecimals = await rewardTokenContract.decimals();

console.log("Refund amount:", ethers.utils.formatUnits(refundAmount, rewardTokenDecimals));

} else {
console.log(`Ending incentive on ${networkName} network is not supported...`);
}
};

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Loading

0 comments on commit e1513ff

Please sign in to comment.