@mstable/protocol
Version:
mStable Contracts
138 lines (137 loc) • 7.68 kB
JavaScript
"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