diff --git a/contracts/constants.tact b/contracts/constants.tact
index 302f59f..dda02ed 100644
--- a/contracts/constants.tact
+++ b/contracts/constants.tact
@@ -5,6 +5,8 @@ const ACTION_LIQUIDATION: Int = 3;
const RERUN_ACTION_UPDATE_POSITION: Int = 100;
const RERUN_ACTION_MINT: Int = 101;
+const RERUN_ACTION_TOKEN_TRANSFER: Int = 102;
+const RERUN_ACTION_TOKEN_BURN: Int = 103;
const JETTON_UNIT: Int = pow(10, 9);
// Mock zero address
diff --git a/contracts/jetton/assetToken/atoken-wallet.tact b/contracts/jetton/assetToken/atoken-wallet.tact
index 3a19524..ff792a4 100644
--- a/contracts/jetton/assetToken/atoken-wallet.tact
+++ b/contracts/jetton/assetToken/atoken-wallet.tact
@@ -147,7 +147,7 @@ contract ATokenDefaultWallet
queryId: msg.queryId,
amount: msg.amount,
owner: self.owner,
- response_destination: self.owner
+ response_destination: msg.response_destination
}.toCell()
}
);
diff --git a/contracts/jetton/assetToken/atoken.tact b/contracts/jetton/assetToken/atoken.tact
index 950429a..67c57c7 100644
--- a/contracts/jetton/assetToken/atoken.tact
+++ b/contracts/jetton/assetToken/atoken.tact
@@ -28,7 +28,7 @@ contract AToken with ATokenJettonTrait {
self.requireOwner();
self.requireNotStopped();
require(self.mintable, "Can't Mint Anymore");
- self.mint(msg.queryId, msg.receiver, msg.amount, self.owner); // (to, amount, response_destination)
+ self.mint(msg.queryId, msg.receiver, msg.amount, self.owner); // (queryId, to, amount, response_destination)
}
// ====== Get Methods ====== //
diff --git a/contracts/jetton/debtToken/dtoken-master.tact b/contracts/jetton/debtToken/dtoken-master.tact
index 1723433..4be029a 100644
--- a/contracts/jetton/debtToken/dtoken-master.tact
+++ b/contracts/jetton/debtToken/dtoken-master.tact
@@ -40,7 +40,7 @@ trait DTokenJettonTrait with Ownable, Deployable, Resumable {
// @to The Address receive the Jetton token after minting
// @amount The amount of Jetton token being minted
// @response_destination The previous owner address
- fun mint(to: Address, amount: Int, response_destination: Address) {
+ fun mint(queryId: Int, to: Address, amount: Int, response_destination: Address) {
self.totalSupply = (self.totalSupply + amount); // Update total supply
let winit: StateInit = self.getJettonWalletInit(to); // Create message
@@ -50,7 +50,7 @@ trait DTokenJettonTrait with Ownable, Deployable, Resumable {
bounce: false,
mode: SendRemainingValue,
body: TokenTransferInternal{
- queryId: 0,
+ queryId: queryId,
amount: amount,
from: myAddress(),
response_destination: response_destination,
diff --git a/contracts/jetton/debtToken/dtoken-wallet.tact b/contracts/jetton/debtToken/dtoken-wallet.tact
index e0a2b85..1aa2439 100644
--- a/contracts/jetton/debtToken/dtoken-wallet.tact
+++ b/contracts/jetton/debtToken/dtoken-wallet.tact
@@ -92,7 +92,7 @@ contract DTokenDefaultWallet
queryId: msg.queryId,
amount: msg.amount,
owner: self.owner,
- response_destination: self.owner
+ response_destination: msg.response_destination
}.toCell()
}
);
diff --git a/contracts/jetton/debtToken/dtoken.tact b/contracts/jetton/debtToken/dtoken.tact
index d05e253..60a33e0 100644
--- a/contracts/jetton/debtToken/dtoken.tact
+++ b/contracts/jetton/debtToken/dtoken.tact
@@ -28,7 +28,7 @@ contract DToken with DTokenJettonTrait {
self.requireOwner();
self.requireNotStopped();
require(self.mintable, "Can't Mint Anymore");
- self.mint(msg.receiver, msg.amount, self.owner); // (to, amount, response_destination)
+ self.mint(msg.queryId, msg.receiver, msg.amount, self.owner); // (queryId, to, amount, response_destination)
}
// ====== Get Methods ====== //
diff --git a/contracts/jetton/messages.tact b/contracts/jetton/messages.tact
index 6cb3475..5d01741 100644
--- a/contracts/jetton/messages.tact
+++ b/contracts/jetton/messages.tact
@@ -63,7 +63,6 @@ message CheckAndTransferAToken {
// custom Mint message
message Mint {
queryId: Int as uint64;
- token: Address;
amount: Int;
receiver: Address;
}
diff --git a/contracts/pool-view.tact b/contracts/pool-view.tact
index 7cae40b..e510e45 100644
--- a/contracts/pool-view.tact
+++ b/contracts/pool-view.tact
@@ -26,8 +26,10 @@ trait PoolView with Ownable, Resumable {
reservesConfiguration: map
;
reserveInterestRateStrategy: map;
// bounce messages
- updatePositionMsg: map;
- mintMsg: map;
+ updatePositionMsg: map;
+ mintMsg: map;
+ tokenTransferMsg: map;
+ tokenBurnMsg: map;
// ===== Get functions =====
@@ -101,20 +103,13 @@ trait PoolView with Ownable, Resumable {
return self.reservesData.get(reserveAddress)!!;
}
- get fun reserveDataForUI(reserveAddress: Address): ReserveDataForUI {
+ get fun reserveDataAndConfiguration(reserveAddress: Address): ReserveDataAndConfiguration {
let reserveData: ReserveData = self.reservesData.get(reserveAddress)!!;
+ let reserveConfiguration: ReserveConfiguration = self.reservesConfiguration.get(reserveAddress)!!;
return
- ReserveDataForUI{
- liquidityIndex: reserveData.liquidityIndex,
- currentLiquidityRate: reserveData.currentLiquidityRate,
- borrowIndex: reserveData.borrowIndex,
- currentBorrowRate: reserveData.currentBorrowRate,
- totalSupply: reserveData.totalSupply,
- availableLiquidity: reserveData.availableLiquidity,
- accruedToTreasury: reserveData.accruedToTreasury,
- totalBorrow: reserveData.totalBorrow,
- lastUpdateTimestamp: reserveData.lastUpdateTimestamp,
- price: reserveData.price,
+ ReserveDataAndConfiguration{
+ reserveData: reserveData,
+ reserveConfiguration: reserveConfiguration,
normalizedIncome: reserveData.getNormalizedIncome(),
normalizedDebt: reserveData.getNormalizedDebt()
};
@@ -158,14 +153,22 @@ trait PoolView with Ownable, Resumable {
}
get fun bounceMsg(queryId: Int): Cell? {
- let updatePositionMsg: UpdatePosition? = self.updatePositionMsg.get(queryId);
+ let updatePositionMsg: UpdatePositionBounce? = self.updatePositionMsg.get(queryId);
if (updatePositionMsg != null) {
return updatePositionMsg!!.toCell();
}
- let mintMsg: Mint? = self.mintMsg.get(queryId);
+ let mintMsg: MintBounce? = self.mintMsg.get(queryId);
if (mintMsg != null) {
return mintMsg!!.toCell();
}
+ let tokenTransferMsg: TokenTransferBounce? = self.tokenTransferMsg.get(queryId);
+ if (tokenTransferMsg != null) {
+ return tokenTransferMsg!!.toCell();
+ }
+ let tokenBurnMsg: TokenBurnBounce? = self.tokenBurnMsg.get(queryId);
+ if (tokenBurnMsg != null) {
+ return tokenBurnMsg!!.toCell();
+ }
return null;
}
}
\ No newline at end of file
diff --git a/contracts/pool.tact b/contracts/pool.tact
index 75e4e64..b807fad 100644
--- a/contracts/pool.tact
+++ b/contracts/pool.tact
@@ -30,8 +30,10 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
reserveInterestRateStrategy: map;
// bounce messages
- updatePositionMsg: map;
- mintMsg: map;
+ updatePositionMsg: map;
+ mintMsg: map;
+ tokenTransferMsg: map;
+ tokenBurnMsg: map;
init() {
self.owner = sender();
@@ -93,7 +95,7 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
let reserveAddress: Address = msg.tokenAddress;
let reserveConfiguration: ReserveConfiguration? = self.reservesConfiguration.get(reserveAddress);
require(reserveConfiguration != null, "Reserve not found");
-
+ // GetUserAccountData don't need do bounce
send(SendParameters{
to: userAccountAddress,
value: 0,
@@ -116,6 +118,7 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
let reserveAddress: Address = msg.tokenAddress;
let reserveConfiguration: ReserveConfiguration? = self.reservesConfiguration.get(reserveAddress);
require(reserveConfiguration != null, "Reserve not found");
+ // GetUserAccountData don't need do bounce
send(SendParameters{
to: userAccountAddress,
value: 0,
@@ -160,9 +163,9 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
self.reservesData.set(reserveAddress, reserveData);
// Transfer borrowAmount Token(tokenAddress) to the user.
let poolWalletAddress: Address = reserveConfigration.poolWalletAddress;
- self.sendTokenTransferByPool(msg.queryId, poolWalletAddress, msg.user, borrowAmount);
+ self.sendTokenTransferByPool(poolWalletAddress, msg.user, borrowAmount);
// TODO: calculate fees and Ton to send
- self.updateUserAccountPosition(msg.queryId, msg.user, msg.tokenAddress, 0, scaledBorrowAmount);
+ self.updateUserAccountPosition(msg.user, msg.tokenAddress, 0, scaledBorrowAmount);
}
if(msg.action == ACTION_WITHDRAW) {
@@ -177,9 +180,9 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
self.reservesData.set(reserveAddress, reserveData);
// Transfer withdrawAmount Token(tokenAddress) to the user.
let poolWalletAddress: Address = reserveConfigration.poolWalletAddress;
- self.sendTokenTransferByPool(msg.queryId, poolWalletAddress, msg.user, withdrawAmount);
+ self.sendTokenTransferByPool(poolWalletAddress, msg.user, withdrawAmount);
// TODO: calculate fees and Ton to send
- self.updateUserAccountPosition(msg.queryId, msg.user, msg.tokenAddress, -scaledWithdrawAmount, 0);
+ self.updateUserAccountPosition(msg.user, msg.tokenAddress, -scaledWithdrawAmount, 0);
}
}
@@ -196,6 +199,8 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
// we can delete the key of the queryId from `mintMsg` map and `tokenTransferMsg` map in the same time,
// And only one map will be updated.
self.mintMsg.del(msg.queryId);
+ self.tokenTransferMsg.del(msg.queryId);
+ self.tokenBurnMsg.del(msg.queryId);
}
receive(msg: RerunBounceMsg) {
@@ -205,23 +210,51 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
if (msg.action == RERUN_ACTION_MINT) {
self.rerunMintMsg(msg.queryId);
}
+ if (msg.action == RERUN_ACTION_TOKEN_TRANSFER) {
+ self.rerunSendTokenTransferByPool(msg.queryId);
+ }
+ if (msg.action == RERUN_ACTION_TOKEN_BURN) {
+ self.rerunTokenBurnMsg(msg.queryId);
+ }
}
- fun sendTokenTransferByPool(queryId: Int, poolWalletAddress: Address, toAddress: Address, amount: Int) {
+ fun sendTokenTransferByPool(poolWalletAddress: Address, toAddress: Address, amount: Int) {
+ let queryId: Int = self.queryId;
+ let tokenTransferMsg: TokenTransfer = TokenTransfer{
+ queryId: queryId,
+ amount: amount,
+ destination: toAddress,
+ response_destination: myAddress(), // Pool need to receive TokenExcesses message
+ custom_payload: null,
+ forward_ton_amount: 0,
+ forward_payload: emptySlice()
+ };
+ // store TokenTransferBounce
+ let bounceMsg: TokenTransferBounce = TokenTransferBounce{
+ to: poolWalletAddress,
+ user: toAddress,
+ msg: tokenTransferMsg
+ };
+ self.tokenTransferMsg.set(queryId, bounceMsg);
+ self.queryId += 1;
+
send(SendParameters{
to: poolWalletAddress,
value: ton("0.05"),
bounce: true,
mode: SendPayGasSeparately,
- body: TokenTransfer{
- queryId: queryId,
- amount: amount,
- destination: toAddress,
- response_destination: toAddress,
- custom_payload: null,
- forward_ton_amount: 0,
- forward_payload: emptySlice()
- }.toCell()
+ body: tokenTransferMsg.toCell()
+ });
+ }
+
+ fun rerunSendTokenTransferByPool(queryId: Int) {
+ let bounce: TokenTransferBounce = self.tokenTransferMsg.get(queryId)!!;
+ send(SendParameters{
+ to: bounce.to,
+ value: ton("0.05"),
+ bounce: true,
+ mode: SendPayGasSeparately,
+ body: bounce.msg.toCell()
});
}
@@ -281,11 +314,15 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
let queryId: Int = self.queryId;
let mintMsg: Mint = Mint{
queryId: queryId,
- token: aTokenAddress,
amount: amount,
receiver: user
};
- self.mintMsg.set(queryId, mintMsg);
+ let bounce: MintBounce = MintBounce{
+ to: aTokenAddress,
+ user: user,
+ msg: mintMsg
+ };
+ self.mintMsg.set(queryId, bounce);
self.queryId += 1;
send(SendParameters{
@@ -298,61 +335,102 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
}
fun burnAToken(asset: Address, user: Address, amount: Int) {
+ let queryId: Int = self.queryId;
+ let tokenBurnMsg: TokenBurn = TokenBurn{
+ queryId: queryId,
+ amount: amount,
+ owner: user,
+ response_destination: myAddress() // Pool need to receive TokenExcesses message
+ };
+ let to: Address = self.userATokenWalletAddress(asset, user);
+ let bounce: TokenBurnBounce = TokenBurnBounce{
+ to: to,
+ user: user,
+ msg: tokenBurnMsg
+ };
+ self.tokenBurnMsg.set(queryId, bounce);
+ self.queryId += 1;
+
send(SendParameters{
- to: self.userATokenWalletAddress(asset, user),
+ to: to,
value: 0,
bounce: true,
mode: SendRemainingValue,
- body: TokenBurn{
- queryId: self.queryId,
- amount: amount,
- owner: user,
- response_destination: user // This field isn't used in TokenBurn
- }.toCell()
+ body: tokenBurnMsg.toCell()
});
}
fun burnDToken(asset: Address, user: Address, amount: Int) {
+ let queryId: Int = self.queryId;
+ let tokenBurnMsg: TokenBurn = TokenBurn{
+ queryId: queryId,
+ amount: amount,
+ owner: user,
+ response_destination: myAddress() // Pool need to receive TokenExcesses message
+ };
+ let to: Address = self.userDTokenWalletAddress(asset, user);
+ let bounce: TokenBurnBounce = TokenBurnBounce{
+ to: to,
+ user: user,
+ msg: tokenBurnMsg
+ };
+ self.tokenBurnMsg.set(queryId, bounce);
+ self.queryId += 1;
+
send(SendParameters{
- to: self.userDTokenWalletAddress(asset, user),
+ to: to,
value: 0,
bounce: true,
mode: SendRemainingValue,
- body: TokenBurn{
- queryId: self.queryId,
- amount: amount,
- owner: user,
- response_destination: user // This field isn't used in TokenBurn
- }.toCell()
+ body: tokenBurnMsg.toCell()
});
}
- // TODO: handle bounce message
fun mintDToken(asset: Address, user: Address, amount: Int) {
let dTokenAddress: Address = self.reservesConfiguration.get(asset)!!.dTokenAddress;
+ // store mintMsg
+ let queryId: Int = self.queryId;
+ let mintMsg: Mint = Mint{
+ queryId: queryId,
+ amount: amount,
+ receiver: user
+ };
+ let bounce: MintBounce = MintBounce{
+ to: dTokenAddress,
+ user: user,
+ msg: mintMsg
+ };
+ self.mintMsg.set(queryId, bounce);
+ self.queryId += 1;
+
send(SendParameters{
to: dTokenAddress,
value: 0,
bounce: true,
mode: SendRemainingValue,
- body: Mint{
- queryId: self.queryId,
- token: dTokenAddress,
- amount: amount,
- receiver: user
- }.toCell()
+ body: mintMsg.toCell()
});
- self.queryId += 1;
}
fun rerunMintMsg(queryId: Int) {
- let msg: Mint = self.mintMsg.get(queryId)!!;
+ let bounce: MintBounce = self.mintMsg.get(queryId)!!;
send(SendParameters{
- to: msg.token,
+ to: bounce.to,
value: 0,
bounce: true,
mode: SendRemainingValue,
- body: msg.toCell()
+ body: bounce.msg.toCell()
+ });
+ }
+
+ fun rerunTokenBurnMsg(queryId: Int) {
+ let bounce: TokenBurnBounce = self.tokenBurnMsg.get(queryId)!!;
+ send(SendParameters{
+ to: bounce.to,
+ value: 0,
+ bounce: true,
+ mode: SendRemainingValue,
+ body: bounce.msg.toCell()
});
}
@@ -409,7 +487,7 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
reserveData.totalSupply += scaledSupplyAmount;
self.reservesData.set(matchedReserve!!, reserveData);
- self.updateUserAccountPosition(msg.queryId, msg.from, matchedReserve!!, scaledSupplyAmount, 0);
+ self.updateUserAccountPosition(msg.from, matchedReserve!!, scaledSupplyAmount, 0);
}
// use crc32 code of 'Repay': utils.calculateRequestOpcode_1('Repay')
@@ -427,22 +505,27 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
reserveData.totalBorrow -= scaledBorrowAmount;
self.reservesData.set(matchedReserve!!, reserveData);
- self.updateUserAccountPosition(msg.queryId, msg.from, matchedReserve!!, 0, -scaledBorrowAmount);
+ self.updateUserAccountPosition(msg.from, matchedReserve!!, 0, -scaledBorrowAmount);
}
}
- fun updateUserAccountPosition(queryId: Int, ownerAddress: Address, reserveAddress: Address, supply: Int, borrow: Int) {
+ fun updateUserAccountPosition(ownerAddress: Address, reserveAddress: Address, supply: Int, borrow: Int) {
+ let queryId: Int = self.queryId;
let userAccountInit: StateInit = self.getUserAccountInit(ownerAddress);
let userAccountAddress: Address = contractAddress(userAccountInit);
-
let msg: UpdatePosition = UpdatePosition{
queryId: queryId,
- user: ownerAddress,
address: reserveAddress,
supply: supply,
borrow: borrow
};
- self.updatePositionMsg.set(queryId, msg);
+ let updatePositionBounce: UpdatePositionBounce = UpdatePositionBounce{
+ to: userAccountAddress,
+ user: ownerAddress,
+ msg: msg
+ };
+
+ self.updatePositionMsg.set(queryId, updatePositionBounce);
self.queryId += 1;
send(SendParameters{
@@ -458,17 +541,17 @@ contract Pool with Deployable, Ownable, Resumable, PoolView {
// rerun the stored UpdatePositionMsg which isn't deleted in the UserPositionUpdated.
fun rerunUpdatePositionMsg(queryId: Int) {
- let msg: UpdatePosition = self.updatePositionMsg.get(queryId)!!;
+ let bounce: UpdatePositionBounce = self.updatePositionMsg.get(queryId)!!;
- let userAccountInit: StateInit = self.getUserAccountInit(msg.user);
+ let userAccountInit: StateInit = self.getUserAccountInit(bounce.user);
let userAccountAddress: Address = contractAddress(userAccountInit);
send(SendParameters{
- to: userAccountAddress,
+ to: bounce.to,
value: 0,
bounce: true,
mode: SendRemainingValue,
- body: msg.toCell(),
+ body: bounce.msg.toCell(),
code: userAccountInit.code,
data: userAccountInit.data
});
diff --git a/contracts/types/message.tact b/contracts/types/message.tact
index 3efc972..7ba0f18 100644
--- a/contracts/types/message.tact
+++ b/contracts/types/message.tact
@@ -1,4 +1,6 @@
import "./struct";
+import "../jetton/messages";
+
// TODO: update the message id
message(0x66660001) AddReserve {
reserveAddress: Address;
@@ -40,7 +42,6 @@ message(0x66660006) WithdrawToken {
}
message UpdatePosition {
queryId: Int as uint64;
- user: Address;
address: Address;
supply: Int as int128;
borrow: Int as int128;
@@ -61,3 +62,23 @@ message RerunBounceMsg {
queryId: Int as uint64;
action: Int as uint8;
}
+message UpdatePositionBounce {
+ to: Address;
+ user: Address;
+ msg: UpdatePosition;
+}
+message MintBounce {
+ to: Address;
+ user: Address;
+ msg: Mint;
+}
+message TokenTransferBounce {
+ to: Address;
+ user: Address;
+ msg: TokenTransfer;
+}
+message TokenBurnBounce {
+ to: Address;
+ user: Address;
+ msg: TokenBurn;
+}
diff --git a/contracts/types/struct.tact b/contracts/types/struct.tact
index 8cdb89e..c0e2c6b 100644
--- a/contracts/types/struct.tact
+++ b/contracts/types/struct.tact
@@ -38,17 +38,9 @@ struct ReserveData {
price: Int as uint64;
}
-struct ReserveDataForUI {
- liquidityIndex: Int as uint128;
- currentLiquidityRate: Int as uint128;
- borrowIndex: Int as uint128;
- currentBorrowRate: Int as uint128;
- totalSupply: Int as coins;
- availableLiquidity: Int as coins;
- accruedToTreasury: Int as coins;
- totalBorrow: Int as coins;
- lastUpdateTimestamp: Int as uint32;
- price: Int as uint64;
+struct ReserveDataAndConfiguration {
+ reserveData: ReserveData;
+ reserveConfiguration: ReserveConfiguration;
normalizedIncome: Int as uint128;
normalizedDebt: Int as uint128;
}
diff --git a/helpers/constant.ts b/helpers/constant.ts
index 8a551f7..ef82ce3 100644
--- a/helpers/constant.ts
+++ b/helpers/constant.ts
@@ -9,3 +9,5 @@ export const ACTION_LIQUIDATION = 3n;
export const RERUN_ACTION_UPDATE_POSITION = 100n;
export const RERUN_ACTION_MINT = 101n;
+export const RERUN_ACTION_TOKEN_TRANSFER = 102n;
+export const RERUN_ACTION_TOKEN_BURN = 103n;
diff --git a/helpers/pool.ts b/helpers/pool.ts
index a8651e9..1a73fb6 100644
--- a/helpers/pool.ts
+++ b/helpers/pool.ts
@@ -1,19 +1,39 @@
import { Cell } from '@ton/core';
-import { loadMint, loadUpdatePosition, Mint, UpdatePosition } from '../wrappers/Pool';
+import {
+ loadMintBounce,
+ loadTokenBurnBounce,
+ loadTokenTransferBounce,
+ loadUpdatePositionBounce,
+ MintBounce,
+ TokenBurnBounce,
+ TokenTransferBounce,
+ UpdatePositionBounce,
+} from '../wrappers/Pool';
-export const parsePoolBounceMessage = (message: Cell | null): UpdatePosition | Mint | null => {
+export const parsePoolBounceMessage = (
+ message: Cell | null,
+): UpdatePositionBounce | MintBounce | TokenTransferBounce | TokenBurnBounce | null => {
if (message === null) return null;
- const msgSlice = message.asSlice();
try {
- const updatePositionMsg = loadUpdatePosition(msgSlice);
+ const updatePositionMsg = loadUpdatePositionBounce(message.asSlice());
return updatePositionMsg;
} catch (error) {}
try {
- const mintMsg = loadMint(msgSlice);
+ const mintMsg = loadMintBounce(message.asSlice());
return mintMsg;
} catch (error) {}
+
+ try {
+ const tokenTransferMsg = loadTokenTransferBounce(message.asSlice());
+ return tokenTransferMsg;
+ } catch (error) {}
+
+ try {
+ const tokenBurnMsg = loadTokenBurnBounce(message.asSlice());
+ return tokenBurnMsg;
+ } catch (error) {}
console.log('Failed to parse bounce message');
return null;
};
diff --git a/scripts/mintJetton.ts b/scripts/mintJetton.ts
index 14819eb..c5dfa9e 100644
--- a/scripts/mintJetton.ts
+++ b/scripts/mintJetton.ts
@@ -27,7 +27,6 @@ export async function run(provider: NetworkProvider, args: string[]) {
{
$$type: 'Mint',
queryId: 0n,
- token: sampleJetton.address,
receiver: userAddress,
amount: 1000000000000n,
}
diff --git a/tests/Pool.Borrow.spec.ts b/tests/Pool.Borrow.spec.ts
index 8e8810b..5b5ea89 100644
--- a/tests/Pool.Borrow.spec.ts
+++ b/tests/Pool.Borrow.spec.ts
@@ -228,7 +228,6 @@ describe('Pool', () => {
{
$$type: 'Mint',
queryId: 0n,
- token: sampleJetton.address,
amount: toNano(100n),
receiver: deployer.address,
},
diff --git a/tests/Pool.Calculation.spec.ts b/tests/Pool.Calculation.spec.ts
index bafac3a..80276e9 100644
--- a/tests/Pool.Calculation.spec.ts
+++ b/tests/Pool.Calculation.spec.ts
@@ -164,7 +164,6 @@ describe('Pool indexes calculation', () => {
{
$$type: 'Mint',
queryId: 0n,
- token: sampleJetton.address,
amount: toNano(10000n),
receiver: deployer.address,
},
@@ -178,7 +177,6 @@ describe('Pool indexes calculation', () => {
{
$$type: 'Mint',
queryId: 0n,
- token: sampleJetton.address,
amount: toNano(10000n),
receiver: secondUser.address,
},
@@ -353,7 +351,7 @@ describe('Pool indexes calculation', () => {
const supplyAmount = toNano(100n);
await supply(deployer.getSender(), supplyAmount);
- let reserveData = await pool.getReserveDataForUi(sampleJetton.address);
+ let reserveData = (await pool.getReserveDataAndConfiguration(sampleJetton.address)).reserveData;
// no debts, no rates
expect(reserveData.liquidityIndex).toEqual(RAY);
expect(reserveData.borrowIndex).toEqual(RAY);
@@ -362,7 +360,7 @@ describe('Pool indexes calculation', () => {
await sleep(5 * 1000);
- reserveData = await pool.getReserveDataForUi(sampleJetton.address);
+ reserveData = (await pool.getReserveDataAndConfiguration(sampleJetton.address)).reserveData;
// no debts, no rates
expect(reserveData.liquidityIndex).toEqual(RAY);
expect(reserveData.borrowIndex).toEqual(RAY);
@@ -370,7 +368,7 @@ describe('Pool indexes calculation', () => {
expect(reserveData.currentBorrowRate).toEqual(0n);
await supply(secondUser.getSender(), supplyAmount);
- reserveData = await pool.getReserveDataForUi(sampleJetton.address);
+ reserveData = (await pool.getReserveDataAndConfiguration(sampleJetton.address)).reserveData;
// no debts, no rates
expect(reserveData.liquidityIndex).toEqual(RAY);
expect(reserveData.borrowIndex).toEqual(RAY);
@@ -378,11 +376,12 @@ describe('Pool indexes calculation', () => {
expect(reserveData.currentBorrowRate).toEqual(0n);
await sleep(5 * 1000);
- let reserveDataBefore = await pool.getReserveDataForUi(sampleJetton.address);
+ let reserveDataBefore = (await pool.getReserveDataAndConfiguration(sampleJetton.address)).reserveData;
const borrowAmount = toNano(50n);
await borrow(secondUser.getSender(), borrowAmount);
await sleep(5 * 1000);
- reserveData = await pool.getReserveDataForUi(sampleJetton.address);
+ const reserveDataAndConfiguration = await pool.getReserveDataAndConfiguration(sampleJetton.address);
+ reserveData = reserveDataAndConfiguration.reserveData
// first borrow, the index still should be RAY, the rates should not be zero
expect(reserveData.liquidityIndex).toEqual(RAY);
expect(reserveData.borrowIndex).toEqual(RAY);
@@ -407,24 +406,24 @@ describe('Pool indexes calculation', () => {
// non-zero debts, non-zero rates
// normalizedIncome is the real-time liquidityIndex
// normalizedDebt is the real-time borrowIndex
- expect(reserveData.normalizedIncome).toEqual(
+ expect(reserveDataAndConfiguration.normalizedIncome).toEqual(
await mathUtils.getCalculateLinearInterest(
reserveData.currentLiquidityRate,
reserveData.lastUpdateTimestamp,
),
);
- expect(reserveData.normalizedDebt).toEqual(
+ expect(reserveDataAndConfiguration.normalizedDebt).toEqual(
await mathUtils.getCalculateCompoundedInterest(
reserveData.currentBorrowRate,
reserveData.lastUpdateTimestamp,
),
);
- const normalizedIncomeBefore = reserveData.normalizedIncome;
- const normalizedDebtBefore = reserveData.normalizedDebt;
+ const normalizedIncomeBefore = reserveDataAndConfiguration.normalizedIncome;
+ const normalizedDebtBefore = reserveDataAndConfiguration.normalizedDebt;
reserveDataBefore = reserveData;
await supply(deployer.getSender(), supplyAmount);
await sleep(5 * 1000);
- reserveData = await pool.getReserveDataForUi(sampleJetton.address);
+ reserveData = (await pool.getReserveDataAndConfiguration(sampleJetton.address)).reserveData;
// after the first borrow, the other action will update the indexes.
expect(reserveData.liquidityIndex).toEqual(normalizedIncomeBefore);
expect(reserveData.borrowIndex).toEqual(normalizedDebtBefore);
diff --git a/tests/Pool.Repay.spec.ts b/tests/Pool.Repay.spec.ts
index eea9403..0c337b2 100644
--- a/tests/Pool.Repay.spec.ts
+++ b/tests/Pool.Repay.spec.ts
@@ -219,7 +219,6 @@ describe('Pool', () => {
{
$$type: 'Mint',
queryId: 0n,
- token: sampleJetton.address,
amount: toNano(100n),
receiver: deployer.address,
},
diff --git a/tests/Pool.Supply.spec.ts b/tests/Pool.Supply.spec.ts
index c8e68ce..7ed23d0 100644
--- a/tests/Pool.Supply.spec.ts
+++ b/tests/Pool.Supply.spec.ts
@@ -6,6 +6,7 @@ import {
ReserveConfiguration,
ReserveInterestRateStrategy,
UpdatePosition,
+ UpdatePositionBounce,
} from '../wrappers/Pool';
import '@ton/test-utils';
import { SampleJetton } from '../build/SampleJetton/tact_SampleJetton';
@@ -156,7 +157,6 @@ describe('Pool Supply', () => {
{
$$type: 'Mint',
queryId: 0n,
- token: sampleJetton.address,
amount: 100000000000n,
receiver: deployer.address,
},
@@ -400,13 +400,13 @@ describe('Pool Supply', () => {
expect(accountData.positionsLength).toEqual(0n);
let msgId = (await pool.getQueryId()) - 1n;
- const updatePositionMsg = parsePoolBounceMessage(await pool.getBounceMsg(msgId)) as UpdatePosition;
- expect(updatePositionMsg?.$$type).toEqual('UpdatePosition');
- expect(updatePositionMsg?.queryId).toEqual(msgId);
+ const updatePositionMsg = parsePoolBounceMessage(await pool.getBounceMsg(msgId)) as UpdatePositionBounce;
+ expect(updatePositionMsg?.$$type).toEqual('UpdatePositionBounce');
+ expect(updatePositionMsg?.msg.queryId).toEqual(msgId);
expect(updatePositionMsg?.user.toString()).toEqual(deployer.getSender().address.toString());
- expect(updatePositionMsg?.address.toString()).toEqual(sampleJetton.address.toString());
- expect(updatePositionMsg?.supply).toEqual(100000000000n);
- expect(updatePositionMsg?.borrow).toEqual(0n);
+ expect(updatePositionMsg?.msg.address.toString()).toEqual(sampleJetton.address.toString());
+ expect(updatePositionMsg?.msg.supply).toEqual(100000000000n);
+ expect(updatePositionMsg?.msg.borrow).toEqual(0n);
result = await pool.send(
deployer.getSender(),
diff --git a/tests/Pool.Withdraw.spec.ts b/tests/Pool.Withdraw.spec.ts
index 67a670c..1af6444 100644
--- a/tests/Pool.Withdraw.spec.ts
+++ b/tests/Pool.Withdraw.spec.ts
@@ -1,6 +1,13 @@
import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox';
import { address, beginCell, Cell, fromNano, toNano } from '@ton/core';
-import { ATokenDTokenContents, Pool, ReserveConfiguration, ReserveInterestRateStrategy } from '../wrappers/Pool';
+import {
+ ATokenDTokenContents,
+ Pool,
+ ReserveConfiguration,
+ ReserveInterestRateStrategy,
+ TokenBurnBounce,
+ UpdatePositionBounce,
+} from '../wrappers/Pool';
import '@ton/test-utils';
import { SampleJetton } from '../build/SampleJetton/tact_SampleJetton';
import { buildOnchainMetadata } from '../scripts/utils';
@@ -9,9 +16,10 @@ import { UserAccount } from '../build/Pool/tact_UserAccount';
import { DTokenDefaultWallet } from '../build/DToken/tact_DTokenDefaultWallet';
import { AToken } from '../wrappers/AToken';
import { DToken } from '../wrappers/DToken';
-import { PERCENTAGE_FACTOR } from '../helpers/constant';
+import { PERCENTAGE_FACTOR, RERUN_ACTION_TOKEN_BURN, RERUN_ACTION_UPDATE_POSITION } from '../helpers/constant';
import { ATokenDefaultWallet } from '../build/AToken/tact_ATokenDefaultWallet';
import { sleep } from '@ton/blueprint';
+import { parsePoolBounceMessage } from '../helpers/pool';
describe('Pool Withdraw', () => {
let blockchain: Blockchain;
@@ -295,7 +303,6 @@ describe('Pool Withdraw', () => {
{
$$type: 'Mint',
queryId: 0n,
- token: sampleJetton.address,
amount: 100000000000n,
receiver: deployer.address,
},
@@ -305,15 +312,329 @@ describe('Pool Withdraw', () => {
await supplyFromDeployer(supplyAmount);
});
- it('withdraw successfully with no debt', async () => {
- const userAccountAddress = await UserAccount.fromInit(pool.address, deployer.address);
+ // it('withdraw successfully with no debt', async () => {
+ // const userAccountAddress = await UserAccount.fromInit(pool.address, deployer.address);
+ // const withdrawAmount = toNano(50n);
+ // const deployerJettonBalanceBefore = (await deployerJettonDefaultWallet.getGetWalletData()).balance;
+
+ // const result = await pool.send(
+ // deployer.getSender(),
+ // {
+ // value: toNano('1.5'),
+ // },
+ // {
+ // $$type: 'WithdrawToken',
+ // tokenAddress: sampleJetton.address,
+ // amount: withdrawAmount,
+ // },
+ // );
+
+ // // WithdrawToken
+ // expect(result.transactions).toHaveTransaction({
+ // from: deployer.address,
+ // to: pool.address,
+ // success: true,
+ // });
+
+ // // GetUserAccountData
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: userAccountAddress.address,
+ // success: true,
+ // });
+
+ // // UserAccountDataResponse
+ // expect(result.transactions).toHaveTransaction({
+ // from: userAccountAddress.address,
+ // to: pool.address,
+ // success: true,
+ // });
+
+ // // sendTokenTransferByPool TokenTransfer
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: poolWallet.address,
+ // success: true,
+ // });
+
+ // // UpdatePosition
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: userAccountAddress.address,
+ // success: true,
+ // });
+
+ // // UserPositionUpdated
+ // expect(result.transactions).toHaveTransaction({
+ // from: userAccountAddress.address,
+ // to: pool.address,
+ // success: true,
+ // });
+
+ // // Burn aToken
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: deployerATokenDefaultWallet.address,
+ // success: true,
+ // });
+
+ // // aToken-wallet to aToken-master TokenBurnNotification
+ // expect(result.transactions).toHaveTransaction({
+ // from: deployerATokenDefaultWallet.address,
+ // to: aToken.address,
+ // success: true,
+ // });
+
+ // const userAccountContract = blockchain.openContract(userAccountAddress);
+ // const accountData = await userAccountContract.getAccount();
+ // expect(accountData.positionsDetail?.get(sampleJetton.address)!!.supply).toEqual(supplyAmount - withdrawAmount);
+ // expect(accountData.positionsDetail?.get(sampleJetton.address)!!.borrow).toEqual(toNano(0n));
+
+ // const walletData = await deployerATokenDefaultWallet.getGetWalletData();
+ // expect(walletData.balance).toEqual(supplyAmount - withdrawAmount);
+ // expect((await deployerJettonDefaultWallet.getGetWalletData()).balance).toEqual(
+ // deployerJettonBalanceBefore + withdrawAmount,
+ // );
+ // });
+
+ // it('withdraw max amount successfully with no debt', async () => {
+ // const userAccountAddress = await UserAccount.fromInit(pool.address, deployer.address);
+ // const withdrawAmount = supplyAmount;
+ // const deployerJettonBalanceBefore = (await deployerJettonDefaultWallet.getGetWalletData()).balance;
+ // const result = await pool.send(
+ // deployer.getSender(),
+ // {
+ // value: toNano('0.5'),
+ // },
+ // {
+ // $$type: 'WithdrawToken',
+ // tokenAddress: sampleJetton.address,
+ // amount: withdrawAmount,
+ // },
+ // );
+
+ // // WithdrawToken
+ // expect(result.transactions).toHaveTransaction({
+ // from: deployer.address,
+ // to: pool.address,
+ // success: true,
+ // });
+
+ // // GetUserAccountData
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: userAccountAddress.address,
+ // success: true,
+ // });
+
+ // // UserAccountDataResponse
+ // expect(result.transactions).toHaveTransaction({
+ // from: userAccountAddress.address,
+ // to: pool.address,
+ // success: true,
+ // });
+
+ // // sendTokenTransferByPool TokenTransfer
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: poolWallet.address,
+ // success: true,
+ // });
+
+ // // UpdatePosition
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: userAccountAddress.address,
+ // success: true,
+ // });
+
+ // // UserPositionUpdated
+ // expect(result.transactions).toHaveTransaction({
+ // from: userAccountAddress.address,
+ // to: pool.address,
+ // success: true,
+ // });
+
+ // // Burn aToken
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: deployerATokenDefaultWallet.address,
+ // success: true,
+ // });
+
+ // // aToken-wallet to aToken-master TokenBurnNotification
+ // expect(result.transactions).toHaveTransaction({
+ // from: deployerATokenDefaultWallet.address,
+ // to: aToken.address,
+ // success: true,
+ // });
+
+ // const userAccountContract = blockchain.openContract(userAccountAddress);
+ // const accountData = await userAccountContract.getAccount();
+ // expect(accountData.positionsLength).toEqual(1n);
+ // expect(accountData.positions?.get(0n)!!.equals(sampleJetton.address)).toBeTruthy();
+ // expect(accountData.positionsDetail?.get(sampleJetton.address)!!.supply).toEqual(supplyAmount - withdrawAmount);
+ // expect(accountData.positionsDetail?.get(sampleJetton.address)!!.borrow).toEqual(toNano(0n));
+
+ // const walletData = await deployerATokenDefaultWallet.getGetWalletData();
+ // expect(walletData.balance).toEqual(supplyAmount - withdrawAmount);
+ // expect((await deployerJettonDefaultWallet.getGetWalletData()).balance).toEqual(
+ // deployerJettonBalanceBefore + withdrawAmount,
+ // );
+ // });
+
+ // it('withdraw max amount when user have the debt and check HF successfully', async () => {
+ // const userAccountAddress = await UserAccount.fromInit(pool.address, deployer.address);
+ // const userAccountContract = blockchain.openContract(userAccountAddress);
+
+ // const borrowAmount = toNano(60n);
+ // await borrowFromDeployer(borrowAmount / 2n);
+ // await sleep(5 * 1000);
+ // await borrowFromDeployer(borrowAmount / 2n);
+
+ // const maxWithdrawAmount =
+ // supplyAmount - (borrowAmount * PERCENTAGE_FACTOR) / reserveConfiguration.liquidationThreshold;
+ // // withdraw
+ // const withdrawAmount = maxWithdrawAmount - toNano('0.01');
+ // const deployerJettonBalanceBefore = (await deployerJettonDefaultWallet.getGetWalletData()).balance;
+ // let result = await pool.send(
+ // deployer.getSender(),
+ // {
+ // value: toNano('1.5'),
+ // },
+ // {
+ // $$type: 'WithdrawToken',
+ // tokenAddress: sampleJetton.address,
+ // amount: withdrawAmount,
+ // },
+ // );
+
+ // // WithdrawToken
+ // expect(result.transactions).toHaveTransaction({
+ // from: deployer.address,
+ // to: pool.address,
+ // success: true,
+ // });
+
+ // // GetUserAccountData
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: userAccountAddress.address,
+ // success: true,
+ // });
+
+ // // UserAccountDataResponse
+ // expect(result.transactions).toHaveTransaction({
+ // from: userAccountAddress.address,
+ // to: pool.address,
+ // success: true,
+ // });
+
+ // // sendTokenTransferByPool TokenTransfer
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: poolWallet.address,
+ // success: true,
+ // });
+
+ // // UpdatePosition
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: userAccountAddress.address,
+ // success: true,
+ // });
+
+ // // UserPositionUpdated
+ // expect(result.transactions).toHaveTransaction({
+ // from: userAccountAddress.address,
+ // to: pool.address,
+ // success: true,
+ // });
+
+ // // Burn aToken
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: deployerATokenDefaultWallet.address,
+ // success: true,
+ // });
+
+ // // aToken-wallet to aToken-master TokenBurnNotification
+ // expect(result.transactions).toHaveTransaction({
+ // from: deployerATokenDefaultWallet.address,
+ // to: aToken.address,
+ // success: true,
+ // });
+
+ // let accountData = await userAccountContract.getAccount();
+
+ // expect(Number(fromNano(accountData.positionsDetail?.get(sampleJetton.address)!!.supply))).toBeCloseTo(
+ // Number(fromNano(supplyAmount - withdrawAmount)),
+ // 5,
+ // );
+ // expect(Number(fromNano(accountData.positionsDetail?.get(sampleJetton.address)!!.borrow))).toBeCloseTo(
+ // Number(fromNano(borrowAmount)),
+ // 5,
+ // );
+
+ // const walletData = await deployerATokenDefaultWallet.getGetWalletData();
+ // expect(Number(fromNano(walletData.balance))).toBeCloseTo(Number(fromNano(supplyAmount - withdrawAmount)), 5);
+ // expect((await deployerJettonDefaultWallet.getGetWalletData()).balance).toEqual(
+ // deployerJettonBalanceBefore + withdrawAmount,
+ // );
+ // });
+
+ // it('should bounce if the left supply position cant cover the debt', async () => {
+ // const userAccountAddress = await UserAccount.fromInit(pool.address, deployer.address);
+
+ // const borrowAmount = toNano(60n);
+ // await borrowFromDeployer(borrowAmount);
+
+ // const maxWithdrawAmount =
+ // supplyAmount - (borrowAmount * PERCENTAGE_FACTOR) / reserveConfiguration.liquidationThreshold;
+ // // withdraw
+ // let result = await pool.send(
+ // deployer.getSender(),
+ // {
+ // value: toNano('1.5'),
+ // },
+ // {
+ // $$type: 'WithdrawToken',
+ // tokenAddress: sampleJetton.address,
+ // amount: maxWithdrawAmount + 2n,
+ // },
+ // );
+
+ // // WithdrawToken
+ // expect(result.transactions).toHaveTransaction({
+ // from: deployer.address,
+ // to: pool.address,
+ // success: true,
+ // });
+
+ // // GetUserAccountData
+ // expect(result.transactions).toHaveTransaction({
+ // from: pool.address,
+ // to: userAccountAddress.address,
+ // success: true,
+ // });
+
+ // // UserAccountDataResponse
+ // expect(result.transactions).toHaveTransaction({
+ // from: userAccountAddress.address,
+ // to: pool.address,
+ // success: false,
+ // });
+ // });
+
+ it('withdraw Bounce and rerun', async () => {
+ const userAccount = await UserAccount.fromInit(pool.address, deployer.address);
const withdrawAmount = toNano(50n);
const deployerJettonBalanceBefore = (await deployerJettonDefaultWallet.getGetWalletData()).balance;
- const result = await pool.send(
+ let result = await pool.send(
deployer.getSender(),
{
- value: toNano('1.5'),
+ value: toNano('0.05'),
},
{
$$type: 'WithdrawToken',
@@ -332,13 +653,13 @@ describe('Pool Withdraw', () => {
// GetUserAccountData
expect(result.transactions).toHaveTransaction({
from: pool.address,
- to: userAccountAddress.address,
+ to: userAccount.address,
success: true,
});
// UserAccountDataResponse
expect(result.transactions).toHaveTransaction({
- from: userAccountAddress.address,
+ from: userAccount.address,
to: pool.address,
success: true,
});
@@ -353,193 +674,94 @@ describe('Pool Withdraw', () => {
// UpdatePosition
expect(result.transactions).toHaveTransaction({
from: pool.address,
- to: userAccountAddress.address,
- success: true,
- });
-
- // UserPositionUpdated
- expect(result.transactions).toHaveTransaction({
- from: userAccountAddress.address,
- to: pool.address,
- success: true,
- });
-
- // Burn aToken
- expect(result.transactions).toHaveTransaction({
- from: pool.address,
- to: deployerATokenDefaultWallet.address,
- success: true,
- });
-
- // aToken-wallet to aToken-master TokenBurnNotification
- expect(result.transactions).toHaveTransaction({
- from: deployerATokenDefaultWallet.address,
- to: aToken.address,
- success: true,
+ to: userAccount.address,
+ success: false,
});
- const userAccountContract = blockchain.openContract(userAccountAddress);
- const accountData = await userAccountContract.getAccount();
- expect(accountData.positionsDetail?.get(sampleJetton.address)!!.supply).toEqual(supplyAmount - withdrawAmount);
- expect(accountData.positionsDetail?.get(sampleJetton.address)!!.borrow).toEqual(toNano(0n));
+ let msgId = (await pool.getQueryId()) - 1n;
+ const updatePositionBounce = parsePoolBounceMessage(await pool.getBounceMsg(msgId)) as UpdatePositionBounce;
+ expect(updatePositionBounce.$$type).toEqual('UpdatePositionBounce');
+ expect(updatePositionBounce.to.toString()).toEqual(userAccount.address.toString());
+ expect(updatePositionBounce.user.toString()).toEqual(deployer.getSender().address.toString());
+ expect(updatePositionBounce.msg.$$type).toEqual('UpdatePosition');
+ expect(updatePositionBounce.msg.queryId).toEqual(msgId);
+ expect(updatePositionBounce.msg.address.toString()).toEqual(sampleJetton.address.toString());
+ expect(updatePositionBounce.msg.supply).toEqual(-withdrawAmount);
+ expect(updatePositionBounce.msg.borrow).toEqual(0n);
- const walletData = await deployerATokenDefaultWallet.getGetWalletData();
- expect(walletData.balance).toEqual(supplyAmount - withdrawAmount);
- expect((await deployerJettonDefaultWallet.getGetWalletData()).balance).toEqual(
- deployerJettonBalanceBefore + withdrawAmount,
- );
- });
-
- it('withdraw max amount successfully with no debt', async () => {
- const userAccountAddress = await UserAccount.fromInit(pool.address, deployer.address);
- const withdrawAmount = supplyAmount;
- const deployerJettonBalanceBefore = (await deployerJettonDefaultWallet.getGetWalletData()).balance;
- const result = await pool.send(
+ result = await pool.send(
deployer.getSender(),
{
- value: toNano('0.5'),
+ value: toNano('0.06'),
},
{
- $$type: 'WithdrawToken',
- tokenAddress: sampleJetton.address,
- amount: withdrawAmount,
+ $$type: 'RerunBounceMsg',
+ queryId: msgId,
+ action: RERUN_ACTION_UPDATE_POSITION,
},
);
- // WithdrawToken
+ // RerunBounceMsg
expect(result.transactions).toHaveTransaction({
- from: deployer.address,
+ from: deployer.getSender().address,
to: pool.address,
success: true,
});
-
- // GetUserAccountData
+ // UpdatePosition
expect(result.transactions).toHaveTransaction({
from: pool.address,
- to: userAccountAddress.address,
+ to: userAccount.address,
success: true,
});
-
- // UserAccountDataResponse
+ // UserPositionUpdated
expect(result.transactions).toHaveTransaction({
- from: userAccountAddress.address,
+ from: userAccount.address,
to: pool.address,
success: true,
});
- // sendTokenTransferByPool TokenTransfer
- expect(result.transactions).toHaveTransaction({
- from: pool.address,
- to: poolWallet.address,
- success: true,
- });
-
- // UpdatePosition
- expect(result.transactions).toHaveTransaction({
- from: pool.address,
- to: userAccountAddress.address,
- success: true,
- });
-
// UserPositionUpdated
expect(result.transactions).toHaveTransaction({
- from: userAccountAddress.address,
+ from: userAccount.address,
to: pool.address,
success: true,
});
+ expect(await pool.getBounceMsg(msgId)).toEqual(null);
+
// Burn aToken
expect(result.transactions).toHaveTransaction({
from: pool.address,
to: deployerATokenDefaultWallet.address,
- success: true,
- });
-
- // aToken-wallet to aToken-master TokenBurnNotification
- expect(result.transactions).toHaveTransaction({
- from: deployerATokenDefaultWallet.address,
- to: aToken.address,
- success: true,
+ success: false,
});
- const userAccountContract = blockchain.openContract(userAccountAddress);
- const accountData = await userAccountContract.getAccount();
- expect(accountData.positionsLength).toEqual(1n);
- expect(accountData.positions?.get(0n)!!.equals(sampleJetton.address)).toBeTruthy();
- expect(accountData.positionsDetail?.get(sampleJetton.address)!!.supply).toEqual(supplyAmount - withdrawAmount);
- expect(accountData.positionsDetail?.get(sampleJetton.address)!!.borrow).toEqual(toNano(0n));
-
- const walletData = await deployerATokenDefaultWallet.getGetWalletData();
- expect(walletData.balance).toEqual(supplyAmount - withdrawAmount);
- expect((await deployerJettonDefaultWallet.getGetWalletData()).balance).toEqual(
- deployerJettonBalanceBefore + withdrawAmount,
- );
- });
-
- it('withdraw max amount when user have the debt and check HF successfully', async () => {
- const userAccountAddress = await UserAccount.fromInit(pool.address, deployer.address);
- const userAccountContract = blockchain.openContract(userAccountAddress);
-
- const borrowAmount = toNano(60n);
- await borrowFromDeployer(borrowAmount / 2n);
- await sleep(5 * 1000);
- await borrowFromDeployer(borrowAmount / 2n);
+ msgId = (await pool.getQueryId()) - 1n;
+ const tokenBurnBounce = parsePoolBounceMessage(await pool.getBounceMsg(msgId)) as TokenBurnBounce;
+ expect(tokenBurnBounce.$$type).toEqual('TokenBurnBounce');
+ expect(tokenBurnBounce.to.toString()).toEqual(deployerATokenDefaultWallet.address.toString());
+ expect(tokenBurnBounce.user.toString()).toEqual(deployer.getSender().address.toString());
+ expect(tokenBurnBounce.msg.$$type).toEqual('TokenBurn');
+ expect(tokenBurnBounce.msg.queryId).toEqual(msgId);
+ expect(tokenBurnBounce.msg.amount).toEqual(withdrawAmount);
+ expect(tokenBurnBounce.msg.owner.toString()).toEqual(deployer.getSender().address.toString());
+ expect(tokenBurnBounce.msg.response_destination.toString()).toEqual(pool.address.toString());
- const maxWithdrawAmount =
- supplyAmount - (borrowAmount * PERCENTAGE_FACTOR) / reserveConfiguration.liquidationThreshold;
- // withdraw
- const withdrawAmount = maxWithdrawAmount - toNano('0.01');
- const deployerJettonBalanceBefore = (await deployerJettonDefaultWallet.getGetWalletData()).balance;
- let result = await pool.send(
+ result = await pool.send(
deployer.getSender(),
{
- value: toNano('1.5'),
+ value: toNano('0.05'),
},
{
- $$type: 'WithdrawToken',
- tokenAddress: sampleJetton.address,
- amount: withdrawAmount,
+ $$type: 'RerunBounceMsg',
+ queryId: msgId,
+ action: RERUN_ACTION_TOKEN_BURN,
},
);
- // WithdrawToken
- expect(result.transactions).toHaveTransaction({
- from: deployer.address,
- to: pool.address,
- success: true,
- });
-
- // GetUserAccountData
- expect(result.transactions).toHaveTransaction({
- from: pool.address,
- to: userAccountAddress.address,
- success: true,
- });
-
- // UserAccountDataResponse
- expect(result.transactions).toHaveTransaction({
- from: userAccountAddress.address,
- to: pool.address,
- success: true,
- });
-
- // sendTokenTransferByPool TokenTransfer
+ // RerunBounceMsg
expect(result.transactions).toHaveTransaction({
- from: pool.address,
- to: poolWallet.address,
- success: true,
- });
-
- // UpdatePosition
- expect(result.transactions).toHaveTransaction({
- from: pool.address,
- to: userAccountAddress.address,
- success: true,
- });
-
- // UserPositionUpdated
- expect(result.transactions).toHaveTransaction({
- from: userAccountAddress.address,
+ from: deployer.getSender().address,
to: pool.address,
success: true,
});
@@ -558,64 +780,23 @@ describe('Pool Withdraw', () => {
success: true,
});
- let accountData = await userAccountContract.getAccount();
-
- expect(Number(fromNano(accountData.positionsDetail?.get(sampleJetton.address)!!.supply))).toBeCloseTo(
- Number(fromNano(supplyAmount - withdrawAmount)),
- 5,
- );
- expect(Number(fromNano(accountData.positionsDetail?.get(sampleJetton.address)!!.borrow))).toBeCloseTo(
- Number(fromNano(borrowAmount)),
- 5,
- );
-
- const walletData = await deployerATokenDefaultWallet.getGetWalletData();
- expect(Number(fromNano(walletData.balance))).toBeCloseTo(Number(fromNano(supplyAmount - withdrawAmount)), 5);
- expect((await deployerJettonDefaultWallet.getGetWalletData()).balance).toEqual(
- deployerJettonBalanceBefore + withdrawAmount,
- );
- });
-
- it('should bounce if the left supply position cant cover the debt', async () => {
- const userAccountAddress = await UserAccount.fromInit(pool.address, deployer.address);
-
- const borrowAmount = toNano(60n);
- await borrowFromDeployer(borrowAmount);
-
- const maxWithdrawAmount =
- supplyAmount - (borrowAmount * PERCENTAGE_FACTOR) / reserveConfiguration.liquidationThreshold;
- // withdraw
- let result = await pool.send(
- deployer.getSender(),
- {
- value: toNano('1.5'),
- },
- {
- $$type: 'WithdrawToken',
- tokenAddress: sampleJetton.address,
- amount: maxWithdrawAmount + 2n,
- },
- );
-
- // WithdrawToken
+ // TokenExcesses
expect(result.transactions).toHaveTransaction({
- from: deployer.address,
+ from: aToken.address,
to: pool.address,
success: true,
});
+ expect(await pool.getBounceMsg(msgId)).toEqual(null);
- // GetUserAccountData
- expect(result.transactions).toHaveTransaction({
- from: pool.address,
- to: userAccountAddress.address,
- success: true,
- });
+ const userAccountContract = blockchain.openContract(userAccount);
+ const accountData = await userAccountContract.getAccount();
+ expect(accountData.positionsDetail?.get(sampleJetton.address)!!.supply).toEqual(supplyAmount - withdrawAmount);
+ expect(accountData.positionsDetail?.get(sampleJetton.address)!!.borrow).toEqual(toNano(0n));
- // UserAccountDataResponse
- expect(result.transactions).toHaveTransaction({
- from: userAccountAddress.address,
- to: pool.address,
- success: false,
- });
+ const walletData = await deployerATokenDefaultWallet.getGetWalletData();
+ expect(walletData.balance).toEqual(supplyAmount - withdrawAmount);
+ expect((await deployerJettonDefaultWallet.getGetWalletData()).balance).toEqual(
+ deployerJettonBalanceBefore + withdrawAmount,
+ );
});
});
diff --git a/tests/SampleJetton.spec.ts b/tests/SampleJetton.spec.ts
index 5d097e0..95a5b72 100644
--- a/tests/SampleJetton.spec.ts
+++ b/tests/SampleJetton.spec.ts
@@ -58,7 +58,6 @@ describe('SampleJetton', () => {
{
$$type: 'Mint',
queryId: 0n,
- token: sampleJetton.address,
amount: 1000000000n,
receiver: receiverAddress,
},
diff --git a/tests/TestJettonReceive.spec.ts b/tests/TestJettonReceive.spec.ts
index 58a8d8e..34d2800 100644
--- a/tests/TestJettonReceive.spec.ts
+++ b/tests/TestJettonReceive.spec.ts
@@ -54,7 +54,6 @@ describe('TestJettonReceive', () => {
{
$$type: 'Mint',
queryId: 0n,
- token: sampleJetton.address,
receiver: deployer.getSender().address,
amount: toNano(100000),
},
diff --git a/tests/UserAccount.spec.ts b/tests/UserAccount.spec.ts
index 75732ef..f583523 100644
--- a/tests/UserAccount.spec.ts
+++ b/tests/UserAccount.spec.ts
@@ -43,7 +43,6 @@ describe('UserAccoount', () => {
{
$$type: 'UpdatePosition',
queryId: 1n,
- user: deployer.getSender().address,
address: reserveAddress,
supply: toNano('100'),
borrow: 0n,
@@ -72,7 +71,6 @@ describe('UserAccoount', () => {
{
$$type: 'UpdatePosition',
queryId: 1n,
- user: deployer.getSender().address,
address: reserveAddress,
supply: toNano('100'),
borrow: 0n,
@@ -87,7 +85,6 @@ describe('UserAccoount', () => {
{
$$type: 'UpdatePosition',
queryId: 1n,
- user: deployer.getSender().address,
address: reserveAddress,
supply: -toNano('50'),
borrow: toNano(20n),