Skip to content

feat: modify batcher contract to support erc20 sendMany - #192

Merged
kamleshmugdiya merged 1 commit into
masterfrom
COIN-2782
Feb 4, 2025
Merged

feat: modify batcher contract to support erc20 sendMany#192
kamleshmugdiya merged 1 commit into
masterfrom
COIN-2782

Conversation

@kamleshmugdiya

Copy link
Copy Markdown
Contributor

Ticket: COIN-2782

@gianchandania gianchandania left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests for the method

Comment thread contracts/Batcher.sol Outdated
address[] calldata recipients,
uint256[] calldata amounts
) external lockCall {
require(recipients.length == amounts.length, "Length mismatch");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add other validations which are there in batch method here as well

require(recipients.length != 0, 'Must send to at least one person');
require(recipients.length < 256, 'Too many recipients');

should check what this number should be instead of 256

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also length mismatch error is bit ambiguous. let's make this error message same as batch method

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kept the limit dynamic since it can be different for different chains.
added a function changeBatchTransferLimit to change the limit.

Comment thread contracts/Batcher.sol Outdated
) external lockCall {
require(recipients.length == amounts.length, "Length mismatch");
for (uint256 i = 0; i < recipients.length; i++) {
TransferHelper.safeTransferFrom(token, msg.sender, recipients[i], amounts[i]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally there should not be a case of partial success, either we send successfully to all the recipients, or none of the transfer should go through.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to do partial success with giving less approval.
approval given was 20.
tried to send 30 here.
but it failed.

can you suggest some other way to try where partial success can be possible?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as suggested, I tried to send to 5 recipients while giving the gas limit for only 2.
the tx failed on chain.
https://holesky.etherscan.io/tx/0x42d64222124a57e5ee7135be7794fcf3d81df5563be3b55cb5a4df81803f2bf9

Comment thread contracts/Batcher.sol Outdated
) external lockCall {
require(recipients.length != 0, 'Must send to at least one person');
require(recipients.length == amounts.length, "Unequal recipients and values");
for (uint256 i = 0; i < recipients.length; i++) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (uint256 i = 0; i < recipients.length; i++) {
for (uint8 i = 0; i < recipients.length; i++) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://medium.com/coinmonks/mastering-solidity-require-and-custom-errors-in-ethereum-contracts-b491565f1592

You can also change the contract to use custom errors instead of require statements

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used uint16.
also added custom errors.

@kamleshmugdiya

Copy link
Copy Markdown
Contributor Author

Please add tests for the method

added few tests.

Comment thread contracts/Batcher.sol
Comment on lines +9 to +11
error EmptyRecipientsList();
error UnequalRecipientsAndValues();
error TooManyRecipients(uint256 provided, uint256 limit);
error TokenTransferFailed(address token, address from, address to, uint256 amount);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comments following the natspec format for everything

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: comments on errros

Comment thread contracts/Batcher.sol Outdated
Comment thread test/batcher.js Fixed

@sachushaji sachushaji left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good Work!!

Comment thread contracts/Batcher.sol
Comment on lines +9 to +11
error EmptyRecipientsList();
error UnequalRecipientsAndValues();
error TooManyRecipients(uint256 provided, uint256 limit);
error TokenTransferFailed(address token, address from, address to, uint256 amount);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: comments on errros

Comment thread test/batcher.js

@mullapudipruthvik mullapudipruthvik left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
Have we figured out the owner and how do we interact with the contract?

Comment thread contracts/Batcher.sol

IERC20 safeToken = IERC20(token);
for (uint16 i = 0; i < recipients.length; i++) {
safeToken.safeTransferFrom(msg.sender, recipients[i], amounts[i]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we allow 0 value transfers ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will handle it here.
https://bitgoinc.atlassian.net/browse/COIN-3005

what is the expected behaviour?

  1. should it skip the 0 value transfers and continue with other transfers?
  2. fail entirely (keeping it atomic).

@kamleshmugdiya

Copy link
Copy Markdown
Contributor Author

LGTM Have we figured out the owner and how do we interact with the contract?

Not sure about the owner.
I am thinking we will need a script and a workflow (since the owner will be bitgo key) to modify the limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants