@mstable/protocol
Version:
mStable Contracts
574 lines • 28.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MassetMachine = void 0;
const generated_1 = require("types/generated");
const math_1 = require("@utils/math");
const constants_1 = require("@utils/constants");
const standardAccounts_1 = require("./standardAccounts");
class MassetMachine {
async initAccounts(accounts) {
this.sa = await new standardAccounts_1.StandardAccounts().initAccounts(accounts);
return this;
}
// 3 bAssets, custom reserve
async deployLite(a = 135) {
const bAssets = await Promise.all([0, 1, 2].map((i) => this.loadBassetProxy(`${i}BASSET`, `${i}BASSET`, 18)));
// 2. Invariant Validator
const logicLib = await new generated_1.MassetLogic__factory(this.sa.default.signer).deploy();
// 3. Invariant Validator
const ManagerFactory = await new generated_1.MassetManager__factory(this.sa.default.signer);
const managerLib = await ManagerFactory.deploy();
const nexus = await new generated_1.MockNexus__factory(this.sa.default.signer).deploy(this.sa.governor.address, this.sa.mockSavingsManager.address, this.sa.mockInterestValidator.address);
const mAssetFactoryLibs = {
"contracts/masset/MassetLogic.sol:MassetLogic": logicLib.address,
"contracts/masset/MassetManager.sol:MassetManager": managerLib.address,
};
const MassetFactory = new generated_1.ExposedMasset__factory(mAssetFactoryLibs, this.sa.default.signer);
const impl = (await MassetFactory.deploy(nexus.address, math_1.simpleToExactAmount(5, 13)));
const data = impl.interface.encodeFunctionData("initialize", [
"mAsset Lite",
"mLite",
bAssets.map((b) => ({
addr: b.address,
integrator: constants_1.ZERO_ADDRESS,
hasTxFee: false,
status: 0,
})),
{
a: math_1.BN.from(a),
limits: {
min: math_1.simpleToExactAmount(5, 16),
max: math_1.simpleToExactAmount(75, 16),
},
},
]);
const mAsset = await new generated_1.AssetProxy__factory(this.sa.default.signer).deploy(impl.address, constants_1.DEAD_ADDRESS, data);
return {
mAsset: (await MassetFactory.attach(mAsset.address)),
bAssets,
logicLib: logicLib,
nexus,
};
}
async deployMasset(useLendingMarkets = false, useTransferFees = false, a = 100) {
// 1. Bassets
const bAssets = await this.loadBassetsLocal(useLendingMarkets, useTransferFees);
// 2. Invariant Validator
const logicLib = await new generated_1.MassetLogic__factory(this.sa.default.signer).deploy();
// 3. Invariant Validator
const ManagerFactory = await new generated_1.MassetManager__factory(this.sa.default.signer);
const managerLib = await ManagerFactory.deploy();
const nexus = await new generated_1.MockNexus__factory(this.sa.default.signer).deploy(this.sa.governor.address, this.sa.mockSavingsManager.address, this.sa.mockInterestValidator.address);
const integrationAddress = useLendingMarkets
? (await new generated_1.MockPlatformIntegration__factory(this.sa.default.signer).deploy(nexus.address, bAssets.aavePlatformAddress, bAssets.bAssets.map((b) => b.address), bAssets.aTokens.map((at) => at.aToken))).address
: constants_1.ZERO_ADDRESS;
// 3.2. Masset
const mAssetFactoryLibs = {
"contracts/masset/MassetLogic.sol:MassetLogic": logicLib.address,
"contracts/masset/MassetManager.sol:MassetManager": managerLib.address,
};
const MassetFactory = new generated_1.ExposedMasset__factory(mAssetFactoryLibs, this.sa.default.signer);
const impl = (await MassetFactory.deploy(nexus.address, math_1.simpleToExactAmount(5, 13)));
const data = impl.interface.encodeFunctionData("initialize", [
"mStable BTC",
"mBTC",
bAssets.bAssets.map((b, i) => ({
addr: b.address,
integrator: integrationAddress,
hasTxFee: bAssets.bAssetTxFees[i],
status: 0,
})),
{
a,
limits: {
min: math_1.simpleToExactAmount(5, 16),
max: math_1.simpleToExactAmount(65, 16),
},
},
]);
const mAsset = await new generated_1.AssetProxy__factory(this.sa.default.signer).deploy(impl.address, constants_1.DEAD_ADDRESS, data);
if (useLendingMarkets) {
await new generated_1.MockPlatformIntegration__factory(this.sa.default.signer).attach(integrationAddress).addWhitelist([mAsset.address]);
}
return {
mAsset: (await MassetFactory.attach(mAsset.address)),
bAssets: bAssets.bAssets,
aavePlatformAddress: bAssets.aavePlatformAddress,
integrationAddress,
platform: useLendingMarkets
? await new generated_1.MockPlatformIntegration__factory(this.sa.default.signer).attach(integrationAddress)
: null,
pTokens: useLendingMarkets ? bAssets.aTokens.map((at) => at.aToken) : [],
logicLib,
managerLib,
wrappedManagerLib: await ManagerFactory.attach(mAsset.address),
nexus,
};
}
/**
* @dev Seeds the mAsset basket with custom weightings
* @param md Masset details object containing all deployed contracts
* @param weights Whole numbers of mAsset to mint for each given bAsset
*/
async seedWithWeightings(md, weights, inputIsInBaseUnits = false) {
const { mAsset, bAssets } = md;
const approvals = await Promise.all(bAssets.map((b, i) => this.approveMasset(b, mAsset, weights[i], this.sa.default.signer, inputIsInBaseUnits)));
await mAsset.mintMulti(bAssets.map((b) => b.address), approvals, 0, this.sa.default.address);
}
// /**
// * @dev Deploys an mAsset with default parameters, modelled on original mUSD
// * @return Interface will all deployed information
// */
// public async deployMasset(enableUSDTFee = false, useOldAave = false): Promise<MassetDetails> {
// const md: MassetDetails = {};
// /** *************************************
// 0. Mock platforms and bAssets
// Dependencies: []
// *************************************** */
// const bassetDetails = await this.loadBassets(enableUSDTFee, useOldAave);
// md.bAssets = bassetDetails.bAssets;
// /** *************************************
// 2. mUSD
// Dependencies: [
// BasketManager [
// ProxyAdmin,
// PlatformIntegrations [
// MockPlatforms
// ]
// ]
// ]
// *************************************** */
// // 2.0. Deploy ProxyAdmin
// const d_DelayedProxyAdmin: t.DelayedProxyAdminInstance = await c_DelayedProxyAdmin.new(
// this.system.nexus.address,
// {
// from: this.sa.default,
// },
// );
// md.proxyAdmin = d_DelayedProxyAdmin;
// // 2.1. Deploy no Init BasketManager
// // - Deploy Implementation
// const d_BasketManager = await c_BasketManager.new();
// // - Initialize the BasketManager implementation to avoid someone else doing it
// const d_DeadIntegration = await c_DeadIntegration.new();
// const d_DeadErc20 = await c_MockERC20.new("DEAD", "D34", 18, DEAD_ADDRESS, 1);
// await d_BasketManager.initialize(
// DEAD_ADDRESS,
// DEAD_ADDRESS,
// [d_DeadErc20.address],
// [d_DeadIntegration.address],
// [percentToWeight(100).toString()],
// [false],
// );
// // - Deploy Initializable Proxy
// const d_BasketManagerProxy = await c_BasketManagerProxy.new();
// // 2.2. Deploy no Init AaveIntegration
// // - Deploy Implementation with dummy params (this storage doesn't get used)
// const d_AaveIntegration = await (useOldAave
// ? c_AaveIntegration.new()
// : c_AaveV2Integration.new());
// await d_AaveIntegration.initialize(DEAD_ADDRESS, [DEAD_ADDRESS], DEAD_ADDRESS, [], []);
// // - Deploy Initializable Proxy
// const d_AaveIntegrationProxy = await c_VaultProxy.new();
// // 2.3. Deploy no Init CompoundIntegration
// // - Deploy Implementation
// // We do not need platform address for compound
// const d_CompoundIntegration: t.CompoundIntegrationInstance = await c_CompoundIntegration.new();
// await d_CompoundIntegration.initialize(DEAD_ADDRESS, [DEAD_ADDRESS], DEAD_ADDRESS, [], []);
// // - Deploy Initializable Proxy
// const d_CompoundIntegrationProxy = await c_VaultProxy.new();
// md.basketManager = await c_BasketManager.at(d_BasketManagerProxy.address);
// md.aaveIntegration = await c_AaveIntegration.at(d_AaveIntegrationProxy.address);
// md.compoundIntegration = await c_CompoundIntegration.at(d_CompoundIntegrationProxy.address);
// // 2.4. Deploy mUSD (w/ BasketManager addr)
// // 2.4.1. Deploy ForgeValidator
// const d_ForgeValidator = await c_ForgeValidator.new({
// from: this.sa.default,
// });
// md.forgeValidator = d_ForgeValidator;
// // 2.4.2. Deploy mUSD
// // Deploy implementation
// const d_mUSD = await c_Masset.new();
// await d_mUSD.initialize("", "", DEAD_ADDRESS, DEAD_ADDRESS, DEAD_ADDRESS);
// // Deploy proxy
// const d_mUSDProxy = await c_AssetProxy.new();
// // Initialize proxy
// const initializationData_mUSD: string = d_mUSD.contract.methods
// .initialize(
// "mStable Mock",
// "mMOCK",
// this.system.nexus.address,
// d_ForgeValidator.address,
// d_BasketManagerProxy.address,
// )
// .encodeABI();
// await d_mUSDProxy.methods["initialize(address,address,bytes)"](
// d_mUSD.address,
// d_DelayedProxyAdmin.address,
// initializationData_mUSD,
// );
// md.mAsset = await c_Masset.at(d_mUSDProxy.address);
// // 2.5. Init AaveIntegration
// const initializationData_AaveIntegration: string = d_AaveIntegration.contract.methods
// .initialize(
// this.system.nexus.address,
// [d_mUSDProxy.address, d_BasketManagerProxy.address],
// bassetDetails.aavePlatformAddress,
// bassetDetails.aTokens.map((a) => a.bAsset),
// bassetDetails.aTokens.map((a) => a.aToken),
// )
// .encodeABI();
// await d_AaveIntegrationProxy.methods["initialize(address,address,bytes)"](
// d_AaveIntegration.address,
// d_DelayedProxyAdmin.address,
// initializationData_AaveIntegration,
// );
// // 2.6. Init CompoundIntegration
// const initializationData_CompoundIntegration: string = d_CompoundIntegration.contract.methods
// .initialize(
// this.system.nexus.address,
// [d_mUSDProxy.address, d_BasketManagerProxy.address],
// ZERO_ADDRESS, // We don't need Compound sys addr
// bassetDetails.cTokens.map((c) => c.bAsset),
// bassetDetails.cTokens.map((c) => c.cToken),
// )
// .encodeABI();
// await d_CompoundIntegrationProxy.methods["initialize(address,address,bytes)"](
// d_CompoundIntegration.address,
// d_DelayedProxyAdmin.address,
// initializationData_CompoundIntegration,
// );
// // 2.7. Init BasketManager
// const weight = 100;
// const initializationData_BasketManager: string = d_BasketManager.contract.methods
// .initialize(
// this.system.nexus.address,
// d_mUSDProxy.address,
// bassetDetails.bAssets.map((b) => b.address),
// bassetDetails.platforms.map((p) =>
// p === Platform.aave
// ? d_AaveIntegrationProxy.address
// : d_CompoundIntegrationProxy.address,
// ),
// bassetDetails.bAssets.map(() => percentToWeight(weight).toString()),
// bassetDetails.fees,
// )
// .encodeABI();
// await d_BasketManagerProxy.methods["initialize(address,address,bytes)"](
// d_BasketManager.address,
// d_DelayedProxyAdmin.address,
// initializationData_BasketManager,
// );
// return md;
// }
// public async loadBassets(
// enableUSDTFee = false,
// useOldAave = false,
// ): Promise<BassetIntegrationDetails> {
// return this.system.isGanacheFork
// ? this.loadBassetsFork(enableUSDTFee)
// : this.loadBassetsLocal(enableUSDTFee, useOldAave);
// }
// public async loadBassetsFork(enableUSDTFee = false): Promise<BassetIntegrationDetails> {
// // load all the REAL bAssets
// const bAsset_DAI = await c_MockERC20.at(this.ma.DAI);
// await this.mintERC20(bAsset_DAI, this.ma.FUND_SOURCES.dai);
// const bAsset_USDC = await c_MockERC20.at(this.ma.USDC);
// await this.mintERC20(bAsset_USDC, this.ma.FUND_SOURCES.usdc);
// const bAsset_TUSD = await c_MockERC20.at(this.ma.TUSD);
// await this.mintERC20(bAsset_TUSD, this.ma.FUND_SOURCES.tusd);
// const bAsset_USDT = await c_MockERC20.at(this.ma.USDT);
// await this.mintERC20(bAsset_USDT, this.ma.FUND_SOURCES.usdt);
// const mockUSDT = await c_MockUSDT.at(bAsset_USDT.address);
// if (enableUSDTFee) {
// // Set fee rate to 0.1% and max fee to 30 USDT
// await mockUSDT.setParams("10", "30", {
// from: this.ma.USDT_OWNER,
// });
// } else {
// // Set fee rate to 0.1% and max fee to 30 USDT
// await mockUSDT.setParams("0", "30", {
// from: this.ma.USDT_OWNER,
// });
// }
// // credit sa.default with ample balances
// const bAssets = [bAsset_DAI, bAsset_USDC, bAsset_TUSD, bAsset_USDT];
// // return all the addresses
// return {
// bAssets,
// fees: [false, false, false, enableUSDTFee],
// platforms: [Platform.compound, Platform.compound, Platform.aave, Platform.aave],
// aavePlatformAddress: this.ma.aavePlatform,
// aTokens: [
// {
// bAsset: bAsset_TUSD.address,
// aToken: this.ma.aTUSD,
// },
// {
// bAsset: bAsset_USDT.address,
// aToken: this.ma.aUSDT,
// },
// ],
// cTokens: [
// {
// bAsset: bAsset_DAI.address,
// cToken: this.ma.cDAI,
// },
// {
// bAsset: bAsset_USDC.address,
// cToken: this.ma.cUSDC,
// },
// ],
// };
// }
async loadBassetProxy(name, sym, dec, recipient = this.sa.default.address, init = 10000000000, enableUSDTFee = false) {
// Factories
const tokenFactory = enableUSDTFee
? await new generated_1.MockInitializableTokenWithFee__factory(this.sa.default.signer)
: await new generated_1.MockInitializableToken__factory(this.sa.default.signer);
const AssetProxyFactory = new generated_1.AssetProxy__factory(this.sa.default.signer);
// Impl
const mockInitializableToken = (await tokenFactory.deploy());
// Proxy
const data = await mockInitializableToken.interface.encodeFunctionData("initialize", [name, sym, dec, recipient, init]);
const mAssetProxy = await AssetProxyFactory.deploy(mockInitializableToken.address, this.sa.governor.address, data);
const mAsset = generated_1.MockERC20__factory.connect(mAssetProxy.address, this.sa.default.signer);
return mAsset;
}
async loadBassetsLocal(useLendingMarkets = false, useTransferFees = false, recipient = this.sa.default.address) {
// - Mock bAssets
const mockBasset1 = await this.loadBassetProxy("Ren BTC", "renBTC", 18, recipient);
const mockBasset2 = await this.loadBassetProxy("Synthetix BTC", "sBTC", 6, recipient);
const mockBasset3 = await this.loadBassetProxy("Wrapped BTC", "wBTC", 12, recipient, 10000000000, useTransferFees);
const mockBasset4 = await this.loadBassetProxy("Binance Wrapped BTC", "bBTC", 18, recipient, 10000000000, useTransferFees);
const bAssets = [mockBasset1, mockBasset2, mockBasset3, mockBasset4];
// bAssets at index 2 and 3 only have transfer fees if useTransferFees is true
const bAssetTxFees = bAssets.map((_, i) => useTransferFees && (i === 2 || i === 3));
// Only deploy Aave mock and A tokens if lending markets are required
const lendingProperties = useLendingMarkets ? await this.loadATokens(bAssets) : {};
return {
aavePlatformAddress: constants_1.ZERO_ADDRESS,
aTokens: [],
...lendingProperties,
bAssets,
bAssetTxFees,
};
}
/**
* Deploy a mocked Aave contract.
* For each bAsset:
* - transfer some bAsset tokens to the Aave mock
* - deploy a new mocked A token for the bAsset
* - add new A token to the mAsset platform integration
* @param bAssets
* @returns
*/
async loadATokens(bAssets) {
// - Mock Aave integration
const mockAave = await new generated_1.MockAaveV2__factory(this.sa.default.signer).deploy();
await Promise.all(bAssets.map(async (b) => b.transfer(mockAave.address, (await b.totalSupply()).div(1000))));
// - Mock aTokens
const aTokenFactory = new generated_1.MockATokenV2__factory(this.sa.default.signer);
const mockATokens = await Promise.all(bAssets.map((b) => aTokenFactory.deploy(mockAave.address, b.address)));
// - Add to the Platform
await Promise.all(bAssets.map((b, i) => mockAave.addAToken(mockATokens[i].address, b.address)));
return {
aavePlatformAddress: mockAave.address,
aTokens: bAssets.map((b, i) => ({
bAsset: b.address,
aToken: mockATokens[i].address,
})),
};
}
// public async mintERC20(
// erc20: t.MockERC20Instance,
// source: Address,
// recipient: string = this.sa.default,
// ): Promise<Truffle.TransactionResponse<any>> {
// const decimals = await erc20.decimals();
// return erc20.transfer(recipient, simpleToExactAmount(1000, decimals), {
// from: source,
// });
// }
// /**
// * @dev Deploy a Masset via the Manager then:
// * 1. Mint with optimal weightings
// */
// public async deployMassetAndSeedBasket(
// enableUSDTFee = false,
// initialSupply = 100,
// ): Promise<MassetDetails> {
// const mAssetDetails = await this.deployMasset(enableUSDTFee);
// // Mint initialSupply with shared weightings
// const basketDetails = await this.getBassetsInMasset(mAssetDetails);
// // Calc optimal weightings
// const totalWeighting = basketDetails.reduce((p, c) => {
// return p.add(new BN(c.maxWeight));
// }, new BN(0));
// const totalMintAmount = simpleToExactAmount(initialSupply, 18);
// const mintAmounts = await Promise.all(
// basketDetails.map(async (b) => {
// // e.g. 5e35 / 2e18 = 2.5e17
// const relativeWeighting = new BN(b.maxWeight).mul(fullScale).div(totalWeighting);
// // e.g. 1e20 * 25e16 / 1e18 = 25e18
// const mintAmount = totalMintAmount.mul(relativeWeighting).div(fullScale);
// // const bAssetDecimals: BN = await b.decimals();
// // const decimalDelta = new BN(18).sub(bAssetDecimals);
// return mintAmount.mul(ratioScale).div(new BN(b.ratio));
// }),
// );
// // Approve bAssets
// await Promise.all(
// mAssetDetails.bAssets.map((b, i) =>
// b.approve(mAssetDetails.mAsset.address, mintAmounts[i].muln(2), {
// from: this.system.sa.default,
// }),
// ),
// );
// await mAssetDetails.mAsset.mintMulti(
// basketDetails.map((b) => b.addr),
// mintAmounts,
// this.system.sa.default,
// { from: this.system.sa.default },
// );
// await mAssetDetails.mAsset.mintMulti(
// basketDetails.map((b) => b.addr),
// mintAmounts,
// this.system.sa.default,
// { from: this.system.sa.default },
// );
// return mAssetDetails;
// }
async getBassetsInMasset(mAssetDetails) {
const [personal, data] = await mAssetDetails.mAsset.getBassets();
const bArrays = personal.map((b, i) => {
const d = data[i];
return {
addr: b.addr,
status: b.status,
isTransferFeeCharged: b.hasTxFee,
ratio: math_1.BN.from(d.ratio),
vaultBalance: math_1.BN.from(d.vaultBalance),
integratorAddr: b.integrator,
};
});
const bAssetContracts = await Promise.all(bArrays.map((b) => generated_1.MockERC20__factory.connect(b.addr, this.sa.default.signer)));
const integrators = await Promise.all(bArrays.map((b) => b.integratorAddr === constants_1.ZERO_ADDRESS
? null
: generated_1.MockPlatformIntegration__factory.connect(b.integratorAddr, this.sa.default.signer)));
return bArrays.map((b, i) => ({
...b,
contract: bAssetContracts[i],
integrator: integrators[i],
}));
}
async getBasset(mAssetDetails, bAssetAddress) {
const bAsset = await mAssetDetails.mAsset.getBasset(bAssetAddress);
const bAssetContract = generated_1.MockERC20__factory.connect(bAsset.personal.addr, this.sa.default.signer);
const integrator = bAsset.personal.integrator === constants_1.ZERO_ADDRESS
? null
: (await new generated_1.MockPlatformIntegration__factory(this.sa.default.signer).attach(bAsset.personal.integrator));
return {
addr: bAsset.personal.addr,
status: bAsset.personal.status,
isTransferFeeCharged: bAsset.personal.hasTxFee,
ratio: math_1.BN.from(bAsset.bData.ratio),
vaultBalance: math_1.BN.from(bAsset.bData.vaultBalance),
integratorAddr: bAsset.personal.integrator,
contract: bAssetContract,
pToken: integrator ? await integrator.callStatic["bAssetToPToken(address)"](bAsset.personal.addr) : null,
integrator,
};
}
async getBasketComposition(mAssetDetails) {
// raw bAsset data
const bAssets = await this.getBassetsInMasset(mAssetDetails);
const [failed, undergoingRecol] = await mAssetDetails.mAsset.getBasket();
// total supply of mAsset
const supply = await mAssetDetails.mAsset.totalSupply();
const { surplus } = await mAssetDetails.mAsset.data();
// get actual balance of each bAsset
const rawBalances = await Promise.all(bAssets.map((b) => b.integrator ? b.contract.balanceOf(b.integrator.address) : b.contract.balanceOf(mAssetDetails.mAsset.address)));
const platformBalances = await Promise.all(bAssets.map((b) => (b.integrator ? b.integrator.callStatic.checkBalance(b.addr) : math_1.BN.from(0))));
const balances = rawBalances.map((b, i) => b.add(platformBalances[i]));
// get overweight
const currentVaultUnits = bAssets.map((b) => math_1.BN.from(b.vaultBalance).mul(math_1.BN.from(b.ratio)).div(constants_1.ratioScale));
// get total amount
const sumOfBassets = currentVaultUnits.reduce((p, c) => p.add(c), math_1.BN.from(0));
return {
bAssets: bAssets.map((b, i) => ({
...b,
address: b.addr,
mAssetUnits: currentVaultUnits[i],
actualBalance: balances[i],
rawBalance: rawBalances[i],
platformBalance: platformBalances[i],
})),
totalSupply: supply,
surplus,
sumOfBassets,
failed,
undergoingRecol,
};
}
/**
* @dev Takes a whole unit approval amount, and converts it to the equivalent
* base asset amount, before approving and returning the exact approval
* @param bAsset Asset to approve spending of
* @param mAsset Masset that gets permission to spend
* @param fullMassetUnits Whole number or fraction to approve
* @param sender Set if needed, else fall back to default
* @param inputIsBaseUnits Override the scaling up to MassetQ
*/
async approveMasset(bAsset, mAsset, fullMassetUnits, sender = this.sa.default.signer, inputIsBaseUnits = false) {
const bAssetDecimals = await bAsset.decimals();
const approvalAmount = inputIsBaseUnits ? math_1.BN.from(fullMassetUnits) : math_1.simpleToExactAmount(fullMassetUnits, bAssetDecimals);
await bAsset.connect(sender).approve(mAsset.address, approvalAmount);
return approvalAmount;
}
async approveMassetMulti(bAssets, mAsset, fullMassetUnits, sender) {
const result = Promise.all(bAssets.map((b) => this.approveMasset(b, mAsset, fullMassetUnits, sender)));
return result;
}
static async getPlatformInteraction(mAsset, type, amount, bAsset) {
const hasIntegrator = bAsset.integratorAddr === constants_1.ZERO_ADDRESS;
const integratorBalBefore = await bAsset.contract.balanceOf(bAsset.integrator ? bAsset.integratorAddr : mAsset.address);
if (hasIntegrator) {
return {
hasLendingMarket: false,
expectInteraction: false,
rawBalance: type === "deposit" ? integratorBalBefore.add(amount) : integratorBalBefore.sub(amount),
};
}
const hasTxFee = bAsset.isTransferFeeCharged;
if (hasTxFee) {
return {
hasLendingMarket: true,
expectInteraction: true,
amount,
rawBalance: math_1.BN.from(0),
};
}
const totalSupply = await mAsset.totalSupply();
const { cacheSize, surplus } = await mAsset.data();
const maxC = totalSupply.add(surplus).mul(constants_1.ratioScale).div(math_1.BN.from(bAsset.ratio)).mul(cacheSize).div(constants_1.fullScale);
const newSum = math_1.BN.from(integratorBalBefore).add(amount);
const expectInteraction = type === "deposit" ? newSum.gte(maxC) : amount.gt(math_1.BN.from(integratorBalBefore));
return {
hasLendingMarket: true,
expectInteraction,
amount: type === "deposit"
? newSum.sub(maxC.div(2))
: math_1.minimum(maxC.div(2).add(amount).sub(math_1.BN.from(integratorBalBefore)), math_1.BN.from(bAsset.vaultBalance).sub(math_1.BN.from(integratorBalBefore))),
rawBalance: type === "deposit"
? expectInteraction
? maxC.div(2)
: newSum
: expectInteraction
? math_1.minimum(maxC.div(2), math_1.BN.from(bAsset.vaultBalance).sub(amount))
: math_1.BN.from(integratorBalBefore).sub(amount),
};
}
}
exports.MassetMachine = MassetMachine;
//# sourceMappingURL=mAssetMachine.js.map