UNPKG

@mstable/protocol

Version:
138 lines (137 loc) 7.68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.splitBuyBackRewards = exports.calculateBuyBackRewardsQuote = void 0; const math_1 = require("@utils/math"); const generated_1 = require("types/generated"); const uniswap_1 = require("@utils/peripheral/uniswap"); /** * Calculate the minBassetsAmounts, minRewardsAmounts and uniswapPaths to execute on the buyback rewards. * * @param {Signer} signer * @param {MainParams} params * - mAssets: Addresses of mAssets that are to be sold for rewards. eg mUSD and mBTC. * - revenueSplitBuyBackAddress: The address of the revenue split buy back contract.; * @return {Promise<BuyBackRewardsParams>} * - minBassetsAmounts Minimum amount of bAsset tokens to receive for each redeem of mAssets. * The amount uses the decimal places of the bAsset. * Example 1: Redeeming 10,000 mUSD with a min 2% slippage to USDC which has 6 decimal places * minBassetsAmounts = 10,000 mAssets * slippage 0.98 * USDC decimals 1e6 = * 1e4 * 0.98 * 1e6 = 1e10 * 0.98 = 98e8 * * Example 2: Redeeming 1 mBTC with a min 5% slippage to WBTC which has 8 decimal places * minBassetsAmounts = 1 mAsset * slippage 0.95 * WBTC decimals 1e8 = * 0.95 * 1e8 = 95e6 * * - minRewardsAmounts Minimum amount of reward tokens received from the sale of bAssets. * The amount uses the decimal places of the rewards token. * Example 1: Swapping 10,000 USDC with a min 1% slippage to MTA which has 18 decimal places * minRewardsAmounts = 10,000 USDC * slippage 0.99 * MTA decimals 1e18 * MTA/USD rate 1.2 * = 1e4 * 0.99 * 1e18 * 1.2 = 1e22 * 0.99 = 99e20 * * Example 1: Swapping 1 WBTC with a min 3% slippage to MTA which has 18 decimal places * minRewardsAmounts = 1 WBTC * slippage 0.97 * MTA decimals 1e18 * MTA/BTC rate 0.00001 * = 1 * 0.97 * 1e18 * 0.00001 = 0.97 * 1e13 = 97e11 * * - uniswapPaths The Uniswap V3 bytes encoded paths. */ const calculateBuyBackRewardsQuote = async (signer, params) => { const { revenueSplitBuyBack, mAssets, swapFees, blockNumber } = params; const mAssetsToBuyBack = []; const minBassetsAmounts = []; const minRewardsAmounts = []; const uniswapPaths = []; const configScale = await revenueSplitBuyBack.CONFIG_SCALE(); const treasuryFee = await revenueSplitBuyBack.treasuryFee(); const rewardsToken = await revenueSplitBuyBack.REWARDS_TOKEN(); const rewardsTokenContract = generated_1.ERC20__factory.connect(rewardsToken, signer); const rTokenDecimals = await rewardsTokenContract.decimals(); const rTokenSymbol = await rewardsTokenContract.symbol(); for (let i = 0; i < mAssets.length; i = 1 + 1) { const mAsset = mAssets[i]; const bAsset = await revenueSplitBuyBack.bassets(mAsset.address); const mAssetContract = generated_1.ERC20__factory.connect(mAsset.address, signer); const bAssetContract = generated_1.ERC20__factory.connect(bAsset, signer); const mAssetBalance = await mAssetContract.balanceOf(revenueSplitBuyBack.address); const mAssetSymbol = await mAssetContract.symbol(); const bAssetDecimals = await bAssetContract.decimals(); const bAssetSymbol = await bAssetContract.symbol(); // console.log(`ts: ${mAssetSymbol} balance: ${mAssetBalance.toString()}`); // Validate if the mAsset balance is grater than the minimum balance to buy back, default is zero. if (mAssetBalance.gt(mAsset.mAssetMinBalance)) { // mAssetAmount = 10000e18 * (1e18 - 0.4e18 / 1e18) = 6000e18 const mAssetAmount = mAssetBalance.mul(configScale.sub(treasuryFee)).div(configScale); // calculate minBassetsAmounts const bAssetSlippage = 100 - mAsset.bAssetMinSlippage; // mAssetAmount = 6000e18 * (98/100)/1e18 * 1e6 = 5880e6 (USDC) const minBassetsAmount = mAssetAmount .mul(bAssetSlippage) .div(100) .div(math_1.simpleToExactAmount(1)) .mul(math_1.simpleToExactAmount(1, bAssetDecimals)); minBassetsAmounts.push(minBassetsAmount); mAssetsToBuyBack.push(mAsset); // console for debugging purposes, do not delete console.table({ mAssetSymbol, mAssetBalance: mAssetBalance.toString(), configScale: configScale.toString(), treasuryFee: treasuryFee.toString(), bAssetSlippage: bAssetSlippage.toString(), bAssetDecimals: bAssetDecimals.toString(), mAssetAmount: mAssetAmount.toString(), minBassetsAmount: minBassetsAmount.toString(), }); // 2 ============ minRewardsAmount ============// const fromToken = { address: bAsset, decimals: bAssetDecimals }; const toToken = { address: rewardsToken, decimals: rTokenDecimals }; // eslint-disable-next-line no-await-in-loop const { outAmount, exchangeRate } = await uniswap_1.quoteSwap(signer, fromToken, toToken, minBassetsAmount, blockNumber, undefined, swapFees); const rewardSlippage = 100 - mAsset.rewardMinSlippage; // minRewardsAmount = 5880e6 * (98/100) /1e6 * 1e18 = 5880e6 (USDC) // quote out amount of reward tokens with its decimals. const minRewardsAmount = outAmount.mul(rewardSlippage).div(100); minRewardsAmounts.push(minRewardsAmount); // console for debugging purposes, do not delete console.table({ bAssetSymbol, rTokenSymbol, rewardSlippage: rewardSlippage.toString(), mAssetAmount: mAssetAmount.toString(), minBassetsAmount: minBassetsAmount.toString(), minRewardsAmount: minRewardsAmount.toString(), outAmount: outAmount.toString(), exchangeRate: exchangeRate.toString(), bAssetDecimals: bAssetDecimals.toString(), rTokenDecimals: rTokenDecimals.toString(), }); // 3 ============ Uniswap path ============// const uniswapPath = uniswap_1.encodeUniswapPath(uniswap_1.getWETHPath(bAsset, rewardsToken), [3000, 3000]); uniswapPaths.push(uniswapPath); console.log(`ts: swap ${bAssetSymbol} to ${rTokenSymbol}, encodeUniswapPath: ${uniswapPath.encoded.toString()}`); } } return { ...params, mAssets: mAssetsToBuyBack, minBassetsAmounts, minRewardsAmounts, uniswapPaths }; }; exports.calculateBuyBackRewardsQuote = calculateBuyBackRewardsQuote; /** * Execute the buyback rewards of different mAssets. * * @param {Signer} signer * @param {MainParams} params * @return {*} {Promise<ContractTransaction>} */ const splitBuyBackRewards = async (signer, params) => { const buyBackRewardsParams = await exports.calculateBuyBackRewardsQuote(signer, params); const { mAssets, minBassetsAmounts, minRewardsAmounts, uniswapPaths, revenueSplitBuyBack } = buyBackRewardsParams; const mAssetAddress = mAssets.map((m) => m.address); const uniswapPathsEncoded = uniswapPaths.map((u) => u.encoded); console.log(`ts: buyBackRewards mAssetAddress ${mAssetAddress} minBassetsAmounts ${minBassetsAmounts.toString()} minRewardsAmounts ${minRewardsAmounts.toString()} uniswapPathsEncoded ${uniswapPathsEncoded} `); return revenueSplitBuyBack.buyBackRewards(mAssetAddress, minBassetsAmounts, minRewardsAmounts, uniswapPathsEncoded); }; exports.splitBuyBackRewards = splitBuyBackRewards; //# sourceMappingURL=emissions-split-buy-back.js.map