-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Conditional Splitter ADO #441
Conversation
… for the recipients
…the threshold will be crossed, rename find_threshold to get_threshold
…unds sent and there's no memory of previously sent funds
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First pass looks good, just a few small changes
contracts/finance/andromeda-conditional-splitter/src/contract.rs
Outdated
Show resolved
Hide resolved
// Can't call this function while the lock isn't expired | ||
if let Some(conditional_splitter_lock) = conditional_splitter.lock_time { | ||
ensure!( | ||
conditional_splitter_lock.is_expired(&env.block), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the above comment are applicable to the regular splitter as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should remove it from both, remove it here and then we can remove it from the basic splitter in a separate PR. Seems odd to lock yourself out of the contract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same goes for above
); | ||
|
||
min_value_set.insert(min_value); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if no threshold is set for Uint128::zero()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this unit test illustrates that case: test_execute_send_threshold_not_found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to require a 0 threshold or is that too limiting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be too limiting, but I think we should make it clear to the users that any funds sent below their lowest minimum will cause an error.
…heck for recipient's percentage, EmptyClassId error adjustment, add EmptyThresholdsList error
.generate_amp_msg(&deps.as_ref(), Some(vec_coin))?; | ||
pkt = pkt.add_message(amp_msg); | ||
|
||
// Non-zero checks have already been made for the incoming coins, so we check if the recipient's percentage is above zero. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rounding may cause a non-zero percentage to incur a zero send:
1% of 10 would generate 0.1, rounding would produce a 0 amount
Unless we always round up but that may cause issues with requiring more than 100% of the funds.
let mut vec_coin: Vec<Coin> = Vec::new(); | ||
|
||
let mut recip_coin: Coin = coin.clone(); | ||
recip_coin.amount = coin.amount * recipient_percent; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
recipient_percent
is Decimal
here and coin.amount
is Uint128
? Do we have any concerns of multiplying two differing types here?
Decimal
is a Uint128
but with the last few digits being the "decimal".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In CosmWasm 2.0 they recommend doing the following:
let a = Uint128::new(123);
let b = Decimal::percent(150)
-let c = a * b;
+let c = a.mul_floor(b);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this definitely opens up a zero send edge case, we should protect against that.
…nt before creating amp msg
Motivation
Resolves: #336
Implementation
The splitter's
AddressPercent
struct is used to couple each recipient to a respective percentage.Each threshold has a
min
value and a vector ofAddressPercent
When the
Send
execute msg is called, we find the appropriate threshold for the funds sent with the message, and use its values to calculate for the funds' distribution.The contract owner also has the option to update the thresholds if there's no lock, or if the lock's expired.
Testing
Unit tests and an integration test were created.
Test on G4:
First threshold:
min: 0
one recipient getting 20%
Second threshold:
min: 3
two recipients getting 30% and 60% respectively
Third threshold
min: 10
three recipients getting 40%, 50% and 10% respectively. The last recipient has no funds on testnet, doesn’t exist yet
Instantiation
https://explorer.testnet.andromedaprotocol.io/galileo-4/tx/3C12D67545573EBA2268700B2712E6D7AA74041629C11BA3F236D0BB05E3B3A0
Tx hash for sending 2000000uandr which is 2ANDR (1st threshold)
https://explorer.testnet.andromedaprotocol.io/galileo-4/tx/EA4F02523BC00AD3C85DCB5FB73E239D61B0EF80B0D0170C0F5930207509642D
Tx hash for sending 5000000uandr which is 5ANDR (2nd threshold)
https://explorer.testnet.andromedaprotocol.io/galileo-4/tx/F44F31C17A25F8F0DA5A28E2F5CE4741AAA0F0523E3B7005ECD13223EA011093
Tx hash for sending 10000000uandr which is 10ANDR (exactly at 3rd threshold)
https://explorer.testnet.andromedaprotocol.io/galileo-4/tx/F3C65D7E99994E767C17914858D2D260569B98AA1F3FF4B9E62DD5082DCA3476
Tx hash for sending 200000000uandr which is 200ANDR (3rd threshold)
https://explorer.testnet.andromedaprotocol.io/galileo-4/tx/8F86D8DE4342BFD8AC0DC55700CB0F7FC3526D04A39DA780DD2F93F2453E4765
Notes
lock_time
in instantiation could use the newExpiry
type.It wasn't clear to me how many decimal places I should have included while attaching funds to the
Send
msgSummary by CodeRabbit
Summary by CodeRabbit
New Features
Documentation
Tests