Skip to content

Instantly share code, notes, and snippets.

@charles-cooper
Last active August 29, 2023 16:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save charles-cooper/4df9d1f1b4e504fafe0795cba417d456 to your computer and use it in GitHub Desktop.
Save charles-cooper/4df9d1f1b4e504fafe0795cba417d456 to your computer and use it in GitHub Desktop.
transient storage example in vyper
0x6020610585600039600051630000055c5261055c61002963000000003961055c6020016300000000f3600436101561000d57610551565b60003560e01c34610557576307a1018e81186102f557600435600401610400813511610557578035806040526020820181816060375050506029b3156100c0576010610460527f4a65726b20626f7920752072206f75740000000000000000000000000000000061048052610460506104605180610480018182601f600182031916810190500336823750506308c379a06104205260206104405261046051601f6001820319168101905060440161043cfd5b336029b463ee9387f26104605260208061048052806104800160405180825260208201818183606060045afa9050505080518060208301018182601f600182031916810190500336823750508051602001601f60018203191681019050905081015050333b15610557576000600061044461047c6000335af1610148573d600060003e3d6000fd5b60006000b3600a81116105575780156102e757905b6004810260010180b36104605260018101b36104805260028101b36104a05260038101b36104c0525061048051610580526104a0516105a0526040610560526105608051602082012090506104e052610460516104c051602061055c600039600051808202821582848304141715610557579050905061271080820490509050818183011061055757808201905090506370a082316105005261048051610520526020610500602461051c6104a0515afa61021d573d600060003e3d6000fd5b601f3d1115610557576105005110156102c857602f610540527f596f75206d75737420706179206261636b2074686520706572736f6e20796f75610560527f20626f72726f7765642066726f6d21000000000000000000000000000000000061058052610540506105405180610560018182601f600182031916810190500336823750506308c379a06105005260206105205261054051601f6001820319168101905060440161051cfd5b600060286104e0516020526000526040600020b460010181811861015d575b505060006000b460006029b4005b63e5cd487f811861054f576004358060a01c610557576040526024358060a01c610557576060526064358060a01c610557576080526029b333146103c157603560a0527f4d7573742062652063616c6c65642066726f6d2077697468696e20746865204960c0527f537461727443616c6c6261636b2373746172746564000000000000000000000060e05260a05060a0518060c0018182601f600182031916810190500336823750506308c379a0606052602060805260a051601f60018203191681019050604401607cfd5b604051610140526060516101605260406101205261012080516020820120905060a052602860a0516020526000526040600020b31561048957602d60c0527f416c726561647920626f72726f776564207468697320746f6b656e2066726f6d60e0527f20746869732061646472657373000000000000000000000000000000000000006101005260c05060c0518060e0018182601f600182031916810190500336823750506308c379a0608052602060a05260c051601f60018203191681019050604401609cfd5b6000b36009811161055757600181016000b4600481026001016370a0823160c05260405160e052602060c0602460dc6060515afa6104cc573d600060003e3d6000fd5b601f3d11156105575760c05181b460405160018201b460605160028201b460443560038201b450506001602860a0516020526000526040600020b46323b872dd60c05260405160e0526080516101005260443561012052602060c0606460dc60006060515af1610541573d600060003e3d6000fd5b601f3d11156105575760c050005b505b60006000fd5b600080fd
from vyper.interfaces import ERC20
struct Borrow:
startingBalance: uint256
from_: address
token: ERC20
amount: uint256
interface IStartCallback:
# @notice Called on the `msg.sender` when they call into #start
def started(data: Bytes[1024]): payable
# @notice Anyone can approve a token for this contract, allowing others to borrow their token and earn fees
# @dev Why? Holding custody of certain tokens infers certain rights. E.g.: the ability to vote on a governance proposal.
# @notice The fee in bips that is charged on all borrowing
FEE: immutable(uint256)
@external
def __init__(fee: uint256):
FEE = fee
# @notice The full list of borrows that have happened in the borrow context
borrows: transient(DynArray[Borrow, 10])
# @notice Allow borrowing a particular token from a user only once
alreadyBorrowedToken: transient(HashMap[bytes32, bool])
# @notice The user that is currently borrowing tokens
borrower: transient(address)
# @notice Start borrowing from the users that have approved this contract
@external
def start(data: Bytes[1024]):
assert self.borrower == empty(address), "Jerk boy u r out"
self.borrower = msg.sender
IStartCallback(msg.sender).started(data)
for borrow in self.borrows:
key: bytes32 = keccak256(_abi_encode(borrow.from_, borrow.token))
assert borrow.token.balanceOf(borrow.from_) >= borrow.startingBalance + ((borrow.amount * FEE) / 10_000), "You must pay back the person you borrowed from!"
self.alreadyBorrowedToken[key] = False
self.borrows = []
self.borrower = empty(address)
@external
def borrow(from_: address, token: ERC20, amount: uint256, to: address):
assert msg.sender == self.borrower, "Must be called from within the IStartCallback#started"
key: bytes32 = keccak256(_abi_encode(from_, token))
assert not self.alreadyBorrowedToken[key], "Already borrowed this token from this address"
# Remember the borrower borrowed!
self.borrows.append(Borrow({startingBalance: token.balanceOf(from_), from_: from_, token: token, amount: amount}))
self.alreadyBorrowedToken[key] = True
token.transferFrom(from_, to, amount)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment