Skip to content

Commit 5f87000

Browse files
committed
feat(a_token_factory): add directional rounding to transfer_on_liquidation
- Add rounding_up: bool parameter to control rounding direction - Use ray_div_up when rounding_up=true, ray_div when rounding_up=false - Update liquidation collateral transfer to use rounding_up=true (favor protocol) - Update liquidation protocol fee transfer to use rounding_up=false (favor user) - Update function documentation and inline comments - Fix all affected unit tests to pass new parameter - Align with directional rounding principles and existing API patterns
1 parent 9350db1 commit 5f87000

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

aave-core/sources/aave-logic/liquidation_logic.move

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ module aave_pool::liquidation_logic {
267267
account_address,
268268
vars.actual_collateral_to_liquidate,
269269
index,
270-
vars.collateral_a_token
270+
vars.collateral_a_token,
271+
true // Round up, consistent with burn path, ensure complete liquidation without dust
271272
);
272273

273274
// For the special case of account_address == params.user (self-liquidation) the liquidator_previous_a_token_balance
@@ -809,7 +810,8 @@ module aave_pool::liquidation_logic {
809810
a_token_treasury,
810811
vars.liquidation_protocol_fee_amount,
811812
liquidity_index,
812-
vars.collateral_a_token
813+
vars.collateral_a_token,
814+
false // Round half up, conservative charging, avoid overcharging users
813815
);
814816
};
815817

aave-core/sources/aave-tokens/a_token_factory.move

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -610,21 +610,30 @@ module aave_pool::a_token_factory {
610610
/// @param amount The amount of tokens getting transferred
611611
/// @param index The next liquidity index of the reserve
612612
/// @param metadata_address The address of the aToken
613+
/// @param rounding_up Whether to round up: true=ray_div_up, false=ray_div (round half up)
613614
public(friend) fun transfer_on_liquidation(
614615
from: address,
615616
to: address,
616617
amount: u256,
617618
index: u256,
618-
metadata_address: address
619+
metadata_address: address,
620+
rounding_up: bool
619621
) acquires TokenMap {
620622
assert_token_exists(metadata_address);
621623

622-
// Pre-calculate scaled amount using ray_div (same calculation as token_base::transfer)
624+
// Pre-calculate scaled amount using directional rounding based on rounding_up parameter
623625
// Reasons for pre-calculation:
624626
// 1. Event accuracy: Must match the actual transferred scaled amount for event consistency
625627
// 2. Dust handling: Liquidation protocol fees can be tiny (1-2 octa), which may round to 0
626628
// We must check and skip these dust transfers to prevent assert failure in token_base::transfer
627-
let amount_scaled = wad_ray_math::ray_div(amount, index);
629+
// 3. Directional rounding: rounding_up=true for collateral transfer (favor protocol, consistent with burn),
630+
// rounding_up=false for protocol fees (conservative charging, favor user)
631+
let amount_scaled =
632+
if (rounding_up) {
633+
wad_ray_math::ray_div_up(amount, index) // Round up, consistent with burn path
634+
} else {
635+
wad_ray_math::ray_div(amount, index) // Round half up, conservative charging
636+
};
628637

629638
// Skip transfer if scaled amount is 0 (dust)
630639
// This prevents assertion failure in token_base::transfer
@@ -756,6 +765,6 @@ module aave_pool::a_token_factory {
756765
index: u256,
757766
metadata_address: address
758767
) acquires TokenMap {
759-
transfer_on_liquidation(from, to, amount, index, metadata_address)
768+
transfer_on_liquidation(from, to, amount, index, metadata_address, false) // Use round half up, conservative handling
760769
}
761770
}

aave-core/tests/aave-tokens/a_token_factory_tests.move

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@ module aave_pool::a_token_factory_tests {
327327
transfer_receiver,
328328
20,
329329
reserve_index,
330-
a_token_address
330+
a_token_address,
331+
false // Use round half up for testing
331332
);
332333
assert!(
333334
a_token_factory::scaled_balance_of(transfer_receiver, a_token_address)
@@ -880,7 +881,8 @@ module aave_pool::a_token_factory_tests {
880881
transfer_receiver,
881882
transfer_amount,
882883
reserve_index,
883-
a_token_address
884+
a_token_address,
885+
false // Use round half up for testing
884886
);
885887
assert!(
886888
a_token_factory::scaled_balance_of(transfer_receiver, a_token_address)
@@ -1055,7 +1057,8 @@ module aave_pool::a_token_factory_tests {
10551057
transfer_receiver,
10561058
transfer_amount,
10571059
new_reserve_index,
1058-
a_token_address
1060+
a_token_address,
1061+
false // Use round half up for testing
10591062
);
10601063

10611064
// check emitted events
@@ -1094,7 +1097,8 @@ module aave_pool::a_token_factory_tests {
10941097
transfer_receiver,
10951098
new_transfer_amount,
10961099
new_reserve_index,
1097-
a_token_address
1100+
a_token_address,
1101+
false // Use round half up for testing
10981102
);
10991103

11001104
// check emitted events
@@ -1811,7 +1815,12 @@ module aave_pool::a_token_factory_tests {
18111815
) {
18121816
a_token_factory::test_init_module(aave_pool);
18131817
a_token_factory::transfer_on_liquidation(
1814-
@0x55, @0x66, 100, 1 * wad_ray_math::ray(), @0x22
1818+
@0x55,
1819+
@0x66,
1820+
100,
1821+
1 * wad_ray_math::ray(),
1822+
@0x22,
1823+
false
18151824
);
18161825
}
18171826

0 commit comments

Comments
 (0)