Open charles-cooper opened 6 months ago
from ethereum.ercs import IERC20 @external def do_transfer(token: IERC20, receiver: address, amount: uint256, sig: Bytes[97]): authorize(addr, sig) authcall token.approve(receiver, amount) authcall token.transfer(receiver, amount)
I feel like while it is not necessary to use a context manager based on how this EIP works, we might be able to ensure a little better level of safety by using one:
from ethereum.ercs import IERC20
@external
def do_transfer(token: IERC20, receiver: address, amount: uint256, sig: Bytes[97]):
commit: bytes32 = abi_encode(...) # could be an empty bytes32 literal
with authorize(msg.sender, sig, commit=commit): # Calls `AUTH`
# NOTE: EIP-3074 doesn't require `token.approve` workflow
authcall token.transfer(receiver, amount) # happens within `authorize` context
# authcall outside of context raises compile-time exception
from ethereum.ercs import IERC20 @external def do_transfer(token: IERC20, receiver: address, amount: uint256, sig: Bytes[97]): authorize(addr, sig) authcall token.approve(receiver, amount) authcall token.transfer(receiver, amount)
I feel like while it is not necessary to use a context manager based on how this EIP works, we might be able to ensure a little better level of safety by using one:
from ethereum.ercs import IERC20 @external def do_transfer(token: IERC20, receiver: address, amount: uint256, sig: Bytes[97]): commit: bytes32 = abi_encode(...) # could be an empty bytes32 literal with authorize(msg.sender, sig, commit=commit): # Calls `AUTH` # NOTE: EIP-3074 doesn't require `token.approve` workflow authcall token.transfer(receiver, amount) # happens within `authorize` context # authcall outside of context raises compile-time exception
prank? :)
with prank(msg.sender, sig):
extcall token.transfer(receiver, amount)
but yea it's a somewhat interesting design space because AUTH and AUTHCALL are actually so closely coupled. another possibility is
authcall token.transfer(receiver, amount, auth=sig)
or
token = authorize(address, sig)
# "token" is a compile-time concept which gets erased at runtime
# it is invalidated at compile-time if any other call to `authorize()` happens
extcall token.transfer(receiver, amount, auth=token)
token = authorize(address, sig) # "token" is a compile-time concept which gets erased at runtime # it is invalidated at compile-time if any other call to `authorize()` happens extcall token.transfer(receiver, amount, auth=token)
token
is far too loaded, but this isn't bad
should still be authcall
though
i think with any of the above techniques to link the AUTH invocation with AUTHCALL, we no longer need the authcall
keyword, especially with the scoped thing. like is there any reason you would want to switch between regular and authcall inside of the with authorized(addr, sig):
block?
token = authorize(address, sig) # "token" is a compile-time concept which gets erased at runtime # it is invalidated at compile-time if any other call to `authorize()` happens extcall token.transfer(receiver, amount, auth=token)
token
is far too loaded, but this isn't badshould still be
authcall
though
actually, more I think about this the more I like it. the auth=
kwarg precludes any usage without first doing authorize
. we can keep track of authorization context when compiling and raise when it uses older:
assert extcall token.transfer(receiver, amount, auth=...) # can't do this for obvious reasons
auth1 = authorize(acct1, sig1)
assert extcall token.transfer(receiver, amount, auth=auth1, default_return_value=True)
auth2 = authorize(acct2, sig2) # auth1 is now "stale"
assert extcall token.transfer(receiver, amount, auth=auth2, default_return_value=True)
assert extcall token.transfer(receiver, amount, auth=auth1, default_return_value=True) # raises
Best part is we don't have to argue what happens when you exit context, the context persists until we exit the call, or authorize
is done again
POC, add EIP-3074 support to the language via new
authcall
call type andauthorize()
builtin.What I did
How I did it
How to verify it
example usage:
Commit message
Commit message for the final, squashed PR. (Optional, but reviewers will appreciate it! Please see our commit message style guide for what we would ideally like to see in a commit message.)
Description for the changelog
Cute Animal Picture
![Put a link to a cute animal picture inside the parenthesis-->]()