In my crowdsale contract I have provided a claim function for investors to claim their tokens (PULL). No issues with that.

function claim() external nonReentrant {

However, I would like to provide functionality also to deliver their tokens to investors from the contract admin (PUSH). The first idea would be something like this:

function claimAll() external nonReentrant onlyOwner {
    for (uint i = 0; i < investors.length; i++) {

However, this seems to be a bad practice because the unbounded loop.

So I plan to apply Amortisation of Work and move this loop to client side by providing in the contract:

function claimAddress(address investor) external nonReentrant onlyOwner {

then I would need from client side JS something like

for (var i = 0; i < investors.length; i++) {
    await ICO_CONTRACT?.claimAddress(investors[i]).then(processClaimSuccess).catch(handleError);


  • Is this rationale ok? WDYT?
  • How can I run this client side code in ethersJS without opening metamask to sign every single transaction for each investor? Can I sign to bypass metamask? Can I batch all in a single transaction?

Update1: As I read here, it depends on the wallet that holds the private keys used to sign the transaction. If is a metamask account, metamask should be opened. So, for my case, first thing would be to change the owner of the contract to an account in a wallet that allows signing programmatically.


1 Answer 1


Why don't you use additional mapping which will store the number of tokens each investor is entitled to

mapping(address => uint256) public entitledTokens;

And rather them sending them one by one just make the smart contract in such a way that they can claim their tokens themselves which will be a much more efficient and better approach

function claimTokens() public {
   erc20.transferFrom(owner, msg.sender, entitledTokens[msg.sender])
  • I do this as well but many tokens will be unclaimed so I want to provide an alternative mechanism that we can control. This is the PULL approach I mentioned at the beginning of my post Mar 28, 2023 at 11:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.