diff --git a/README.md b/README.md index 8d4b123..27fc290 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ # fs-cli-v4 -To run the project clone the reposistory and then run: +To run the project clone the repository and then run: ``` yarn ``` +## Setup + Create a .env in the top level containing these keys: ``` @@ -14,12 +16,29 @@ ARBITRUM_RINKEBY_CHAINID=421611 ARBITRUM_RINKEBY_RPC_URL=https://rinkeby.arbitrum.io/rpc ``` -To approve tokens run: +You'll need to allow exchange to take the tokens from you: + +``` +yarn start approveTokens -n arbitrum_rinkeby \ + --exchangeAddress 0x1B5A08020E94066a3fB91Aff8B395De2d9cfaDd2 \ + --asset 100000 --stable 100000 +``` + +Default unit for `asset` is `ether`, that is 18 digits after the dot. +Default unit for `stable` is `6`, meaning 6 digits after the dot. This +matches the `USDC` format. + +You can see currently approved limits: ``` -yarn start approveTokens -n arbitrum_rinkeby -e 0x1B5A08020E94066a3fB91Aff8B395De2d9cfaDd2 +yarn start showAllowance -n arbitrum_rinkeby \ + --exchangeAddress 0x1B5A08020E94066a3fB91Aff8B395De2d9cfaDd2 ``` +Use `approveTokens` to update the exchange allowance. + +## Trade + To trade: ``` @@ -32,6 +51,7 @@ To estimate a trade: yarn start estimateChangePosition -n arbitrum_rinkeby --exchangeAddress 0x1B5A08020E94066a3fB91Aff8B395De2d9cfaDd2 --deltaAsset --deltaStable ``` +## Liquidations To liquidate: ``` diff --git a/src/index.ts b/src/index.ts index ede17c9..759d50d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -186,38 +186,120 @@ const main = async () => { ) .command( ["approveTokens"], - "approve_tokens", - async (yargs: Argv) => yargs, + "approve tokens to be used by the exchange", + async (yargs: Argv) => { + return yargs + .option("asset", { + alias: "a", + describe: + "the amount of asset you want to be accessible to the exchange", + type: "string", + default: ethers.utils.formatUnits("100000"), + }) + .option("assetUnits", { + alias: "A", + describe: "units to use when parsing and showing the asset amounts", + type: "string", + default: "ether", + }) + .option("stable", { + alias: "s", + describe: + "the amount of stable you want to be accessible to the exchange", + type: "string", + default: ethers.utils.formatUnits("100000"), + }) + .option("stableUnits", { + alias: "S", + describe: + "units to use when parsing and showing the stable amounts", + type: "string", + default: "6", + }); + }, async (argv: any) => { + const { + asset: assetAmountRaw, + assetUnits, + stable: stableAmountRaw, + stableUnits, + } = argv; + + const { formatUnits, parseUnits } = ethers.utils; + + const assetAmount = parseUnits(assetAmountRaw, assetUnits); + const stableAmount = parseUnits(stableAmountRaw, stableUnits); + const { accountNumber, networkId, exchangeAddress } = getStandardParams(argv); const wallet = loadAccount(networkId, accountNumber); const exchange = IExchange__factory.connect(exchangeAddress, wallet); - const assetTokenAddress = await exchange.assetToken(); - - const assetToken = IERC20__factory.connect(assetTokenAddress, wallet); + const approve = async (address, tokenName, amount, unit) => { + const token = IERC20__factory.connect(address, wallet); + const tx = await token.approve(exchangeAddress, amount); + await tx.wait(); + const amountStr = formatUnits(amount, unit); + console.log( + `Approved ${amountStr} ${tokenName} tokens to be used by ${exchangeAddress}` + ); + }; - const tx1 = await assetToken.approve( - exchangeAddress, - ethers.utils.parseEther("100000") + await approve( + await exchange.assetToken(), + "asset", + assetAmount, + assetUnits + ); + await approve( + await exchange.stableToken(), + "stable", + stableAmount, + stableUnits ); - await tx1.wait(); + } + ) + .command( + ["showAllowance"], + "show token approved to be used by the exchange", + async (yargs: Argv) => { + return yargs + .option("assetUnits", { + alias: "A", + describe: "units to use when showing the asset amounts", + type: "string", + default: "ether", + }) + .option("stableUnits", { + alias: "S", + describe: "units to use when showing the stable amounts", + type: "string", + default: "6", + }); + }, + async (argv: any) => { + const { formatUnits } = ethers.utils; - const stableTokenAddress = await exchange.stableToken(); + const { assetUnits, stableUnits } = argv; - const stableToken = IERC20__factory.connect(stableTokenAddress, wallet); + const { accountNumber, networkId, exchangeAddress } = + getStandardParams(argv); - const tx2 = await stableToken.approve( - exchangeAddress, - ethers.utils.parseEther("100000") - ); - await tx2.wait(); + const wallet = loadAccount(networkId, accountNumber); + const exchange = IExchange__factory.connect(exchangeAddress, wallet); - console.log( - "Approved both tokens for account: " + (await wallet.getAddress()) - ); + const allowance = async (address, tokenName, unit) => { + const token = IERC20__factory.connect(address, wallet); + const amount = await token.allowance(wallet.address, exchangeAddress); + const amountStr = formatUnits(amount, unit); + console.log( + `Allowance for ${exchangeAddress} for ${tokenName}: ${amountStr}` + ); + }; + + await allowance(await exchange.assetToken(), "asset", assetUnits); + await allowance(await exchange.stableToken(), "stable", stableUnits); } ) .command(