Skip to content
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

takeEvents #142

Merged
merged 4 commits into from
Sep 26, 2023
Merged

takeEvents #142

merged 4 commits into from
Sep 26, 2023

Conversation

martyall
Copy link
Contributor

@martyall martyall commented Sep 25, 2023

Add a function takeEvents that can be used as follows

Assume you have some solidity code as in the example project's PaidSimpleStorage

pragma solidity ^0.8.0;

import "openzeppelin-contracts/token/ERC20/IERC20.sol";

contract SimplePaidStorage {
    IERC20 private _token;
    address private _owner;
    uint public count = 0;

    event CountUpdated(uint newCount);

...

    function updateCount(uint _newCount) external {
        require(
            _token.balanceOf(msg.sender) >= 1,
            "Insufficient tokens to update count"
        );
        require(
            _token.allowance(msg.sender, address(this)) >= 1,
            "Token allowance not set for contract"
        );

        _token.transferFrom(msg.sender, address(this), 1);

        count = _newCount;
        emit CountUpdated(_newCount);
    }

...
}
}

If you call this function, two events will get emitted:

  1. Transfer coming from the ERC20 when the user pays the contract
  2. CountUpdated coming PaidSimpleStorage

If you want to easily catch all the events emitted by a transaction which calls this function, you can now do:

events <- takeEvents someTransaction
      { transfer :: eventFilter (Proxy @ERC20.Transfer) tokenAddress
      , countUpdate :: eventFilter (Proxy @SimplePaidStorage.CountUpdated) paidSimpleStorageAddress
      }
  let (ERC20.Transfer transfer) = unsafePartial $ Array.head events.transfer 
  transfer.value `shouldEqual` events.deposited.value
  transfer.to `shouldEqual` simplePaidStorageAddress

  let (SimplePaidStorage.CountUpdated {newCount} = unsafePartial $ Array.head events.countUpdate
  newCount `shouldEqual` whatever

The events are collected using the transaction hash that caused them. You can actually collect them using any (Applicative f, Monoid (f event), and moreover f can be different for each event if you really wanted. E.g. if the transaction emitted many Transfer events and you only want the first, you could use

  let (SimplePaidStorage.CountUpdated {newCount} = unsafePartial $ Array.head events.countUpdate
  let (ERC20.Transfer transfer) = unsafePartial $ fromJust $ un Last events.transfer 

See the SimplePaidStorageSpec for further usage details

@martyall martyall marked this pull request as ready for review September 25, 2023 20:57
@martyall martyall merged commit 2372d96 into master Sep 26, 2023
3 checks passed
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.

None yet

1 participant