Skip to content

Commit

Permalink
Deploy stargate (#963)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmckelvy1 authored Oct 16, 2023
1 parent f4fa0cd commit 9335ad1
Show file tree
Hide file tree
Showing 12 changed files with 288 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
restore-keys: |
hardhat-network-fork-${{ runner.os }}-
hardhat-network-fork-
- run: npx hardhat test ./test/plugins/individual-collateral/{cbeth,aave-v3,compoundv3}/*.test.ts
- run: npx hardhat test ./test/plugins/individual-collateral/{cbeth,aave-v3,compoundv3,stargate}/*.test.ts
env:
NODE_OPTIONS: '--max-old-space-size=8192'
TS_NODE_SKIP_IGNORE: true
Expand Down
10 changes: 10 additions & 0 deletions common/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,13 @@ export interface ITokens {
cbETH?: string
STG?: string
sUSDC?: string
sUSDbC?: string
sUSDT?: string
sETH?: string
MORPHO?: string
astETH?: string
wsgUSDC?: string
wsgUSDbC?: string

// Morpho Aave
maUSDC?: string
Expand Down Expand Up @@ -115,6 +118,7 @@ interface INetworkConfig {
COMET_EXT?: string
AAVE_V3_INCENTIVES_CONTROLLER?: string
AAVE_V3_POOL?: string
STARGATE_STAKING_CONTRACT?: string
}

export const networkConfig: { [key: string]: INetworkConfig } = {
Expand Down Expand Up @@ -224,6 +228,7 @@ export const networkConfig: { [key: string]: INetworkConfig } = {
COMET_EXT: '0x285617313887d43256F852cAE0Ee4de4b68D45B0',
AAVE_V3_POOL: '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2',
AAVE_V3_INCENTIVES_CONTROLLER: '0x8164Cc65827dcFe994AB23944CBC90e0aa80bFcb',
STARGATE_STAKING_CONTRACT: '0xB0D502E938ed5f4df2E681fE6E419ff29631d62b'
},
'1': {
name: 'mainnet',
Expand Down Expand Up @@ -322,6 +327,7 @@ export const networkConfig: { [key: string]: INetworkConfig } = {
COMET_EXT: '0x285617313887d43256F852cAE0Ee4de4b68D45B0',
AAVE_V3_POOL: '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2',
AAVE_V3_INCENTIVES_CONTROLLER: '0x8164Cc65827dcFe994AB23944CBC90e0aa80bFcb',
STARGATE_STAKING_CONTRACT: '0xB0D502E938ed5f4df2E681fE6E419ff29631d62b'
},
'3': {
name: 'tenderly',
Expand Down Expand Up @@ -420,6 +426,7 @@ export const networkConfig: { [key: string]: INetworkConfig } = {
COMET_EXT: '0x285617313887d43256F852cAE0Ee4de4b68D45B0',
AAVE_V3_POOL: '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2',
AAVE_V3_INCENTIVES_CONTROLLER: '0x8164Cc65827dcFe994AB23944CBC90e0aa80bFcb',
STARGATE_STAKING_CONTRACT: '0xB0D502E938ed5f4df2E681fE6E419ff29631d62b'
},
'5': {
name: 'goerli',
Expand Down Expand Up @@ -522,6 +529,8 @@ export const networkConfig: { [key: string]: INetworkConfig } = {
aBasUSDbC: '0x0a1d576f3eFeF75b330424287a95A366e8281D54',
aWETHv3: '0xD4a0e0b9149BCee3C920d2E00b5dE09138fd8bb7',
acbETHv3: '0xcf3D55c10DB69f28fD1A75Bd73f3D8A2d9c595ad',
sUSDbC: '0x4c80e24119cfb836cdf0a6b53dc23f04f7e652ca',
STG: '0xE3B53AF74a4BF62Ae5511055290838050bf764Df'
},
chainlinkFeeds: {
DAI: '0x591e79239a7d679378ec8c847e5038150364c78f', // 0.3%, 24hr
Expand All @@ -542,6 +551,7 @@ export const networkConfig: { [key: string]: INetworkConfig } = {
COMET_EXT: '0x2F9E3953b2Ef89fA265f2a32ed9F80D00229125B',
AAVE_V3_POOL: '0xA238Dd80C259a72e81d7e4664a9801593F98d1c5',
AAVE_V3_INCENTIVES_CONTROLLER: '0xf9cc4F0D883F1a1eb2c253bdb46c254Ca51E1F44',
STARGATE_STAKING_CONTRACT: '0x06Eb48763f117c7Be887296CDcdfad2E4092739C'
},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ contract StargateRewardableWrapper is RewardableERC20Wrapper {
address(pool_) != address(0),
"Invalid address"
);
require(address(stargate_) == address(stakingContract_.stargate()), "Wrong stargate");
try stakingContract_.stargate() returns (address stargateAddress) {
require(stargateAddress == address(stargate_), "Wrong stargate");
} catch {
// using LPStakingTime contract instead
require(stakingContract_.eToken() == address(stargate_), "Wrong stargate");
}

uint256 poolLength = stakingContract_.poolLength();
uint256 pid = type(uint256).max;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
interface IStargateLPStaking {
function poolLength() external view returns (uint256);

function stargate() external view returns (IERC20);
function stargate() external view returns (address);

function eToken() external view returns (address);

// Info of each pool.
struct PoolInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ contract StargateLPStakingMock is IStargateLPStaking {
mapping(uint256 => mapping(address => uint256)) poolToUserBalance;

ERC20Mock public immutable stargateMock;
IERC20 public immutable stargate;
address public immutable stargate;
address public immutable eToken;

uint256 public totalAllocPoint = 0;

constructor(ERC20Mock stargateMock_) {
stargateMock = stargateMock_;
stargate = stargateMock_;
stargate = address(stargateMock_);
eToken = address(stargateMock_);
}

function poolLength() external view override returns (uint256) {
Expand Down
8 changes: 5 additions & 3 deletions scripts/addresses/base-3.0.0/8453-tmp-assets-collateral.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"USDbC": "0x6490D66B17A1E9a460Ab54131165C8F921aCcDeB",
"cbETH": "0x5fE248625aC2AB0e17A115fef288f17AF1952402",
"cUSDbCv3": "0xa372EC846131FBf9AE8b589efa3D041D9a94dF41",
"aBasUSDbC": "0x1DdB7dfdC5D26FE1f2aD02d9972f12481346Ae9b"
"aBasUSDbC": "0x1DdB7dfdC5D26FE1f2aD02d9972f12481346Ae9b",
"wsgUSDbC": "0x15395aCCbF8c6b28671fe41624D599624709a2D6"
},
"erc20s": {
"COMP": "0x9e1028F5F1D5eDE59748FFceE5532509976840E0",
Expand All @@ -17,6 +18,7 @@
"USDbC": "0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA",
"cbETH": "0x2ae3f1ec7f1f5012cfeab0185bfc7aa3cf0dec22",
"cUSDbCv3": "0xbC0033679AEf41Fb9FeB553Fdf55a8Bb2fC5B29e",
"aBasUSDbC": "0x308447562442Cc43978f8274fA722C9C14BafF8b"
"aBasUSDbC": "0x308447562442Cc43978f8274fA722C9C14BafF8b",
"wsgUSDbC": "0x073F98792ef4c00bB5f11B1F64f13cB25Cde0d8D"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
STAKING_CONTRACT,
SUSDC,
} from '../../../../test/plugins/individual-collateral/stargate/constants'
import { useEnv } from '#/utils/env'

async function main() {
// ==== Read Configuration ====
Expand Down Expand Up @@ -50,19 +51,34 @@ async function main() {

/******** Deploy Stargate USDC Wrapper **************************/

const WrapperFactory: ContractFactory = await hre.ethers.getContractFactory('StargatePoolWrapper')
const WrapperFactory: ContractFactory = await hre.ethers.getContractFactory('StargateRewardableWrapper')
let chainIdKey = useEnv('FORK_NETWORK', 'mainnet') == 'mainnet' ? '1' : '8453'
let USDC_NAME = 'USDC'
let name = 'Wrapped Stargate USDC'
let symbol = 'wsgUSDC'
let sUSDC = networkConfig[chainIdKey].tokens.sUSDC
let oracleError = fp('0.0025')

if (chainIdKey == '8453') {
USDC_NAME = 'USDbC'
name = 'Wrapped Stargate USDbC'
symbol = 'wsgUSDbC'
sUSDC = networkConfig[chainIdKey].tokens.sUSDbC

oracleError = fp('0.003')
}

const erc20 = await WrapperFactory.deploy(
'Wrapped Stargate USDC',
'wSTG-USDC',
networkConfig[chainId].tokens.STG,
STAKING_CONTRACT,
SUSDC
name,
symbol,
networkConfig[chainIdKey].tokens.STG,
networkConfig[chainIdKey].STARGATE_STAKING_CONTRACT,
sUSDC
)
await erc20.deployed()

console.log(
`Deployed Wrapper for Stargate USDC on ${hre.network.name} (${chainId}): ${erc20.address} `
`Deployed Wrapper for Stargate ${USDC_NAME} on ${hre.network.name} (${chainIdKey}): ${erc20.address} `
)

const StargateCollateralFactory: StargatePoolFiatCollateral__factory =
Expand All @@ -73,13 +89,13 @@ async function main() {
).deploy(
{
priceTimeout: priceTimeout.toString(),
chainlinkFeed: networkConfig[chainId].chainlinkFeeds.USDC!,
oracleError: fp('0.0025').toString(), // 0.25%,
chainlinkFeed: networkConfig[chainIdKey].chainlinkFeeds.USDC!,
oracleError: oracleError.toString(),
erc20: erc20.address,
maxTradeVolume: fp('1e6').toString(), // $1m,
oracleTimeout: oracleTimeout(chainId, '86400').toString(), // 24h hr,
oracleTimeout: oracleTimeout(chainIdKey, '86400').toString(), // 24h hr,
targetName: hre.ethers.utils.formatBytes32String('USD'),
defaultThreshold: fp('0.0125').toString(), // 1.25%
defaultThreshold: fp('0.01').add(oracleError).toString(),
delayUntilDefault: bn('86400').toString(), // 24h
},
revenueHiding.toString()
Expand All @@ -88,10 +104,15 @@ async function main() {
await (await collateral.refresh()).wait()
expect(await collateral.status()).to.equal(CollateralStatus.SOUND)

console.log(`Deployed Stargate USDC to ${hre.network.name} (${chainId}): ${collateral.address}`)
console.log(`Deployed Stargate ${USDC_NAME} to ${hre.network.name} (${chainIdKey}): ${collateral.address}`)

assetCollDeployments.collateral.sUSDC = collateral.address
assetCollDeployments.erc20s.sUSDC = erc20.address
if (chainIdKey == '8453') {
assetCollDeployments.collateral.wsgUSDbC = collateral.address
assetCollDeployments.erc20s.wsgUSDbC = erc20.address
} else {
assetCollDeployments.collateral.wsgUSDC = collateral.address
assetCollDeployments.erc20s.wsgUSDC = erc20.address
}
deployedCollateral.push(collateral.address.toString())

fs.writeFileSync(assetCollDeploymentFilename, JSON.stringify(assetCollDeployments, null, 2))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ async function main() {

/******** Deploy Stargate USDT Wrapper **************************/

const WrapperFactory: ContractFactory = await hre.ethers.getContractFactory('StargatePoolWrapper')
const WrapperFactory: ContractFactory = await hre.ethers.getContractFactory('StargateRewardableWrapper')

const erc20 = await WrapperFactory.deploy(
'Wrapped Stargate USDT',
Expand Down
114 changes: 114 additions & 0 deletions scripts/verification/collateral-plugins/verify_stargate_usdc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import hre from 'hardhat'
import { getChainId } from '../../../common/blockchain-utils'
import { baseL2Chains, developmentChains, networkConfig } from '../../../common/configuration'
import { fp, bn } from '../../../common/numbers'
import {
getDeploymentFile,
getAssetCollDeploymentFilename,
IAssetCollDeployments,
} from '../../deployment/common'
import { priceTimeout, oracleTimeout, verifyContract, combinedError, revenueHiding } from '../../deployment/utils'

let deployments: IAssetCollDeployments

async function main() {
// ********** Read config **********
const chainId = await getChainId(hre)
if (!networkConfig[chainId]) {
throw new Error(`Missing network configuration for ${hre.network.name}`)
}

if (developmentChains.includes(hre.network.name)) {
throw new Error(`Cannot verify contracts for development chain ${hre.network.name}`)
}

const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId)
deployments = <IAssetCollDeployments>getDeploymentFile(assetCollDeploymentFilename)

/******** Verify Stargate USDC - wsgUSDC **************************/

if (!baseL2Chains.includes(hre.network.name)) {
const name = 'Wrapped Stargate USDC'
const symbol = 'wsgUSDC'
const sUSDC = networkConfig[chainId].tokens.sUSDC

await verifyContract(
chainId,
deployments.erc20s.wsgUSDC,
[
name,
symbol,
networkConfig[chainId].tokens.STG,
networkConfig[chainId].STARGATE_STAKING_CONTRACT,
sUSDC
],
'contracts/plugins/assets/stargate/StargateRewardableWrapper.sol:StargateRewardableWrapper'
)

const oracleError = fp('0.0025') // 0.25%

await verifyContract(
chainId,
deployments.collateral.wsgUSDC,
[
{
priceTimeout: priceTimeout.toString(),
chainlinkFeed: networkConfig[chainId].chainlinkFeeds.USDC!,
oracleError: oracleError, // 0.25%
erc20: deployments.erc20s.wsgUSDC!,
maxTradeVolume: fp('1e6').toString(), // $1m,
oracleTimeout: oracleTimeout(chainId, '1200').toString(), // 20 min
targetName: hre.ethers.utils.formatBytes32String('USD'),
defaultThreshold: fp('0.01').add(oracleError).toString(),
delayUntilDefault: bn('86400').toString(), // 24h
},
revenueHiding.toString()
],
'contracts/plugins/assets/stargate/StargatePoolFiatCollateral.sol:StargatePoolFiatCollateral'
)
} else if (chainId == '8453' || chainId == '84531') {
const name = 'Wrapped Stargate USDbC'
const symbol = 'wsgUSDbC'
const sUSDC = networkConfig[chainId].tokens.sUSDbC

await verifyContract(
chainId,
deployments.erc20s.wsgUSDbC,
[
name,
symbol,
networkConfig[chainId].tokens.STG,
networkConfig[chainId].STARGATE_STAKING_CONTRACT,
sUSDC
],
'contracts/plugins/assets/stargate/StargateRewardableWrapper.sol:StargateRewardableWrapper'
)

const oracleError = fp('0.003') // 0.3%

await verifyContract(
chainId,
deployments.collateral.wsgUSDbC,
[
{
priceTimeout: priceTimeout.toString(),
chainlinkFeed: networkConfig['8453'].chainlinkFeeds.USDC!,
oracleError: oracleError.toString(),
erc20: deployments.erc20s.wsgUSDbC!,
maxTradeVolume: fp('1e6').toString(), // $1m,
oracleTimeout: oracleTimeout('8453', '86400').toString(), // 24h hr,
targetName: hre.ethers.utils.formatBytes32String('USD'),
defaultThreshold: fp('0.01').add(oracleError).toString(), // ~2.5%
delayUntilDefault: bn('86400').toString(), // 24h
},
revenueHiding.toString()
],
'contracts/plugins/assets/stargate/StargatePoolFiatCollateral.sol:StargatePoolFiatCollateral'
)
}
}

main().catch((error) => {
console.error(error)
process.exitCode = 1
})
12 changes: 8 additions & 4 deletions test/plugins/individual-collateral/collateralTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,17 @@ export default function fn<X extends CollateralFixtureContext>(

itClaimsRewards('claims rewards (via collateral.claimRewards())', async () => {
const amount = bn('20').mul(bn(10).pow(await ctx.tok.decimals()))
await mintCollateralTo(ctx, amount, alice, collateral.address)
await mintCollateralTo(ctx, amount, alice, ctx.collateral.address)
await advanceBlocks(1000)
await setNextBlockTimestamp((await getLatestBlockTimestamp()) + 12000)

const balBefore = await (ctx.rewardToken as IERC20Metadata).balanceOf(collateral.address)
await expect(collateral.claimRewards()).to.emit(ctx.tok, 'RewardsClaimed')
const balAfter = await (ctx.rewardToken as IERC20Metadata).balanceOf(collateral.address)
const balBefore = await (ctx.rewardToken as IERC20Metadata).balanceOf(
ctx.collateral.address
)
await expect(ctx.collateral.claimRewards()).to.emit(ctx.tok, 'RewardsClaimed')
const balAfter = await (ctx.rewardToken as IERC20Metadata).balanceOf(
ctx.collateral.address
)
expect(balAfter).gt(balBefore)
})

Expand Down
Loading

0 comments on commit 9335ad1

Please sign in to comment.