Skip to content

Commit

Permalink
Merge branch 'main' into configure-snx-pool
Browse files Browse the repository at this point in the history
  • Loading branch information
noisekit authored Oct 6, 2023
2 parents f0c1505 + 62d2863 commit 5621528
Show file tree
Hide file tree
Showing 26 changed files with 941 additions and 3 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: e2e

on:
pull_request: {}
push:
branches:
- "main"

jobs:
test:
runs-on: ubuntu-latest
env:
INFURA_API_KEY: ${{ secrets.INFURA_API_KEY }}
strategy:
fail-fast: false
matrix:
toml:
- "omnibus-mainnet.toml"
- "omnibus-optimism-mainnet.toml"
- "omnibus-goerli.toml"
# TODO: re-enable the test when we figure out fix for optimism goerli
#- "omnibus-optimism-goerli.toml"

include:
- toml: "omnibus-mainnet.toml"
chainId: 1
providerUrl: "https://mainnet.infura.io/v3/$INFURA_API_KEY"

- toml: "omnibus-optimism-mainnet.toml"
chainId: 10
providerUrl: "https://optimism-mainnet.infura.io/v3/$INFURA_API_KEY"

- toml: "omnibus-goerli.toml"
chainId: 5
providerUrl: "https://goerli.infura.io/v3/$INFURA_API_KEY"

#- toml: "omnibus-optimism-goerli.toml"
# chainId: 420
# providerUrl: "https://optimism-goerli.infura.io/v3/$INFURA_API_KEY"

steps:
- name: Install Foundry (Cannon)
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- run: anvil -V
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: "18"
cache: "yarn"
- run: yarn --version
- run: yarn install --immutable
- run: yarn build ${{ matrix.chainId }} ${{ matrix.toml }}
- name: "Tests"
run: |
echo "Run anvil"
anvil --fork-url ${{ matrix.providerUrl }} &
echo "Wait for anvil 127.0.0.1:8545"
wget -q -O - --retry-connrefused --waitretry=20 --read-timeout=20 --timeout=15 -t 10 --post-data='{"method":"eth_chainId","params":[],"id":1,"jsonrpc":"2.0"}' --header='Content-Type:application/json' http://127.0.0.1:8545
echo "Execute tests"
yarn test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
.yarn/versions

node_modules
deployments/
129 changes: 129 additions & 0 deletions e2e/fetch-deployments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#!/usr/bin/env node

const path = require('path');
const fs = require('fs/promises');
const toml = require('@iarna/toml');
const { ethers } = require('ethers');
const { OnChainRegistry, IPFSLoader } = require('@usecannon/builder');

const DEFAULT_REGISTRY_ADDRESS = '0x8E5C7EFC9636A6A0408A46BB7F617094B81e5dba';
const CURRENT_DIR = __dirname;
const ROOT = path.resolve(`${CURRENT_DIR}/..`);

async function fetchDeployment({ chainId, deploymentFile, registry, loader }) {
await fs.mkdir(`${CURRENT_DIR}/deployments/${chainId}`, { recursive: true });

const config = await fs.readFile(deploymentFile, 'utf8');
const { name, version, setting } = toml.parse(config);
const preset = setting?.target_preset?.defaultValue ?? 'main';

const snxAddress = setting?.snx_address?.defaultValue ?? ethers.constants.AddressZero;
await fs.writeFile(
`${CURRENT_DIR}/deployments/${chainId}/snx.json`,
JSON.stringify({ address: snxAddress }, null, 2)
);

const ipfs = await registry.getUrl(`${name}:${version}`, `${chainId}-${preset}`);

const meta = {
name,
version,
preset,
ipfs,
chainId,
deploymentFile: path.relative(ROOT, deploymentFile),
};
await fs.writeFile(
`${CURRENT_DIR}/deployments/${chainId}/meta.json`,
JSON.stringify(meta, null, 2)
);

const deployments = await loader.read(ipfs);

const system = deployments.state['provision.system'].artifacts.imports.system;

// TODO: extract other contracts as necessary
// See https://github.com/Synthetixio/synthetix-v3/blob/main/utils/docgen/abis.js for details

const address = system.contracts.CoreProxy.address;
const abi = new ethers.utils.Interface(system.contracts.CoreProxy.abi).format(
ethers.utils.FormatTypes.full
);
await fs.writeFile(
`${CURRENT_DIR}/deployments/${chainId}/CoreProxy.json`,
JSON.stringify({ address, abi }, null, 2)
);
}

async function run() {
const registry = new OnChainRegistry({
signerOrProvider: `https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`,
address: DEFAULT_REGISTRY_ADDRESS,
});
const loader = new IPFSLoader('https://ipfs.synthetix.io');

const [chainId, deploymentFile] = process.argv.slice(2);
if (chainId && deploymentFile) {
await fetchDeployment({ registry, loader, chainId, deploymentFile });
return;
}

await Promise.all([
fetchDeployment({
registry,
loader,
chainId: 1,
deploymentFile: `${ROOT}/omnibus-mainnet.toml`,
}),
fetchDeployment({
registry,
loader,
chainId: 10,
deploymentFile: `${ROOT}/omnibus-optimism-mainnet.toml`,
}),
fetchDeployment({
registry,
loader,
chainId: 5,
deploymentFile: `${ROOT}/omnibus-goerli.toml`,
}),
fetchDeployment({
registry,
loader,
chainId: 420,
deploymentFile: `${ROOT}/omnibus-optimism-goerli.toml`,
}),
fetchDeployment({
registry,
loader,
chainId: 84531,
deploymentFile: `${ROOT}/omnibus-base-goerli.toml`,
}),
fetchDeployment({
registry,
loader,
chainId: 84531,
deploymentFile: `${ROOT}/omnibus-base-goerli-competition.toml`,
}),
fetchDeployment({
registry,
loader,
chainId: 11155111,
deploymentFile: `${ROOT}/omnibus-sepolia.toml`,
}),
fetchDeployment({
registry,
loader,
chainId: 80001,
deploymentFile: `${ROOT}/omnibus-polygon-mumbai.toml`,
}),
fetchDeployment({
registry,
loader,
chainId: 421613,
deploymentFile: `${ROOT}/omnibus-arbitrum-goerli.toml`,
}),
]);
}

run();
26 changes: 26 additions & 0 deletions e2e/tasks/approveCollateral.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const { ethers } = require('ethers');
const { importCoreProxy } = require('./importCoreProxy');
const { getCollateralConfig } = require('./getCollateralConfig');

const log = require('debug')(`tasks:${require('path').basename(__filename, '.js')}`);

async function approveCollateral({ privateKey, symbol }) {
const CoreProxy = await importCoreProxy();
const config = await getCollateralConfig(symbol);
const provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:8545');
const wallet = new ethers.Wallet(privateKey, provider);
log({ wallet: wallet.address, symbol });

const Token = new ethers.Contract(
config.tokenAddress,
['function approve(address spender, uint256 amount) returns (bool)'],
wallet
);
const tx = await Token.approve(CoreProxy.address, ethers.constants.MaxUint256);
await tx.wait();
return null;
}

module.exports = {
approveCollateral,
};
43 changes: 43 additions & 0 deletions e2e/tasks/borrowUsd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const { ethers } = require('ethers');
const { importCoreProxy } = require('./importCoreProxy');
const { getCollateralConfig } = require('./getCollateralConfig');

const log = require('debug')(`tasks:${require('path').basename(__filename, '.js')}`);

async function borrowUsd({ privateKey, accountId, symbol, amount, poolId }) {
const CoreProxy = await importCoreProxy();
const config = await getCollateralConfig(symbol);
const provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:8545');
const wallet = new ethers.Wallet(privateKey, provider);
log({ address: wallet.address, accountId, symbol, amount, poolId });

const coreProxy = new ethers.Contract(CoreProxy.address, CoreProxy.abi, wallet);
const position = await coreProxy.getPositionCollateral(
ethers.BigNumber.from(accountId),
ethers.BigNumber.from(poolId),
config.tokenAddress
);
const maxDebt = position.value.div(config.issuanceRatioD18).toNumber();
const debt = Math.floor(maxDebt);

log({
symbol,
issuanceRatio: parseFloat(ethers.utils.formatUnits(config.issuanceRatioD18)),
positionValue: parseFloat(ethers.utils.formatUnits(position.value)),
maxDebt,
debt,
});
const tx = await coreProxy.mintUsd(
ethers.BigNumber.from(accountId),
ethers.BigNumber.from(poolId),
config.tokenAddress,
ethers.utils.parseEther(`${debt}`),
{ gasLimit: 10_000_000 }
);
await tx.wait();
return debt;
}

module.exports = {
borrowUsd,
};
34 changes: 34 additions & 0 deletions e2e/tasks/createAccount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const { ethers } = require('ethers');
const crypto = require('crypto');
const { importCoreProxy } = require('./importCoreProxy');
const { getAccountOwner } = require('./getAccountOwner');

const log = require('debug')(`tasks:${require('path').basename(__filename, '.js')}`);

async function createAccount({ privateKey, accountId }) {
const CoreProxy = await importCoreProxy();
const provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:8545');
const wallet = new ethers.Wallet(privateKey, provider);
const coreProxy = new ethers.Contract(CoreProxy.address, CoreProxy.abi, wallet);

// const accountId = parseInt(`1337${crypto.randomInt(1000)}`);
const currentAccountOwner = await getAccountOwner({ accountId });
log({ accountId, currentAccountOwner });

if (currentAccountOwner === wallet.address) {
log({ accountId, result: 'SKIP' });
return accountId;
}

const tx = await coreProxy['createAccount(uint128)'](accountId, { gasLimit: 10_000_000 });
await tx.wait();

const newAccountOwner = await getAccountOwner({ accountId });
log({ accountId, newAccountOwner });

return accountId;
}

module.exports = {
createAccount,
};
31 changes: 31 additions & 0 deletions e2e/tasks/delegateCollateral.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { ethers } = require('ethers');
const { getCollateralConfig } = require('./getCollateralConfig');
const { importCoreProxy } = require('./importCoreProxy');

const log = require('debug')(`tasks:${require('path').basename(__filename, '.js')}`);

async function delegateCollateral({ privateKey, accountId, symbol, amount, poolId }) {
const CoreProxy = await importCoreProxy();
const config = await getCollateralConfig(symbol);
const provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:8545');
const wallet = new ethers.Wallet(privateKey, provider);
log({ address: wallet.address, accountId, symbol, amount, poolId });

const coreProxy = new ethers.Contract(CoreProxy.address, CoreProxy.abi, wallet);

const tx = await coreProxy.delegateCollateral(
ethers.BigNumber.from(accountId),
ethers.BigNumber.from(poolId),
config.tokenAddress,
ethers.utils.parseEther(`${amount}`),
ethers.utils.parseEther(`1`),
{ gasLimit: 10_000_000 }
);
await tx.wait();

return accountId;
}

module.exports = {
delegateCollateral,
};
29 changes: 29 additions & 0 deletions e2e/tasks/depositCollateral.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const { ethers } = require('ethers');
const { getCollateralConfig } = require('./getCollateralConfig');
const { importCoreProxy } = require('./importCoreProxy');

const log = require('debug')(`tasks:${require('path').basename(__filename, '.js')}`);

async function depositCollateral({ privateKey, accountId, symbol, amount }) {
const CoreProxy = await importCoreProxy();
const config = await getCollateralConfig(symbol);
const provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:8545');
const wallet = new ethers.Wallet(privateKey, provider);
log({ address: wallet.address, accountId, symbol, amount });

const coreProxy = new ethers.Contract(CoreProxy.address, CoreProxy.abi, wallet);

const tx = await coreProxy.deposit(
ethers.BigNumber.from(accountId),
config.tokenAddress,
ethers.utils.parseEther(`${amount}`),
{ gasLimit: 10_000_000 }
);
await tx.wait();

return accountId;
}

module.exports = {
depositCollateral,
};
25 changes: 25 additions & 0 deletions e2e/tasks/getAccountCollateral.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const { ethers } = require('ethers');
const { getCollateralConfig } = require('./getCollateralConfig');
const { importCoreProxy } = require('./importCoreProxy');

async function getAccountCollateral({ accountId, symbol }) {
const CoreProxy = await importCoreProxy();
const config = await getCollateralConfig(symbol);
const provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:8545');
const coreProxy = new ethers.Contract(CoreProxy.address, CoreProxy.abi, provider);

const [totalDeposited, totalAssigned, totalLocked] = await coreProxy.getAccountCollateral(
accountId,
config.tokenAddress
);

return {
totalDeposited: parseFloat(ethers.utils.formatUnits(totalDeposited)),
totalAssigned: parseFloat(ethers.utils.formatUnits(totalAssigned)),
totalLocked: parseFloat(ethers.utils.formatUnits(totalLocked)),
};
}

module.exports = {
getAccountCollateral,
};
Loading

0 comments on commit 5621528

Please sign in to comment.