From 8d443b27797d45370cd001aa46ede3a2766571c4 Mon Sep 17 00:00:00 2001 From: ross <92001561+z0r0z@users.noreply.github.com> Date: Mon, 29 Apr 2024 10:59:26 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=AA=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gas-snapshot | 6 +- .../Ragequitter.sol/contract.Ragequitter.md | 146 +++++++++++++----- .../src/Ragequitter.sol/interface.IAuth.md | 2 +- lib/solady | 2 +- src/Ragequitter.sol | 22 +-- 5 files changed, 122 insertions(+), 56 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 13797e6..f32f573 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,5 +1,5 @@ -RagequitterTest:testDeploy() (gas: 1733335) +RagequitterTest:testDeploy() (gas: 1762199) RagequitterTest:testInstall() (gas: 34130) -RagequitterTest:testMint() (gas: 79537) -RagequitterTest:testRagequit() (gas: 170251) +RagequitterTest:testMint() (gas: 79585) +RagequitterTest:testRagequit() (gas: 170325) RagequitterTest:testSetURI() (gas: 35986) \ No newline at end of file diff --git a/docs/src/src/Ragequitter.sol/contract.Ragequitter.md b/docs/src/src/Ragequitter.sol/contract.Ragequitter.md index 0130a66..5a83923 100644 --- a/docs/src/src/Ragequitter.sol/contract.Ragequitter.md +++ b/docs/src/src/Ragequitter.sol/contract.Ragequitter.md @@ -1,13 +1,24 @@ # Ragequitter -[Git Source](https://github.com/Moloch-Mystics/ragequit/blob/86d6dd99cf3f73cadf56ed6fdfbc85c29c7189ff/src/Ragequitter.sol) +[Git Source](https://github.com/Moloch-Mystics/ragequit/blob/ed98f5886956972c8e4422a029cd6053d14f537c/src/Ragequitter.sol) **Inherits:** ERC6909 -Simple ragequitter singleton. Uses ERC6909 minimal multitoken. +Simple ragequit singleton with ERC6909 accounting. Version 1. ## State Variables +### ETH +========================= CONSTANTS ========================= /// + +*The conventional ERC7528 ETH address.* + + +```solidity +address internal constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; +``` + + ### _metadata ========================== STORAGE ========================== /// @@ -89,49 +100,54 @@ Reverts if `x * y` overflows, or `d` is zero.* function _mulDiv(uint256 x, uint256 y, uint256 d) internal pure virtual returns (uint256 z); ``` -### install +### mint -======================== INSTALLATION ======================== /// +============================ LOOT ============================ /// -*Initializes ragequit settings for the caller account.* +*Mints loot shares for an owner of the caller account.* ```solidity -function install(Ownership[] calldata owners, Settings calldata setting, Metadata calldata meta) - public - virtual; +function mint(address owner, uint96 shares) public virtual; ``` -### setAuth +### burn -*Sets new authority contract for the caller account.* +*Burns loot shares from an owner of the caller account.* ```solidity -function setAuth(IAuth auth) public virtual; +function burn(address owner, uint96 shares) public virtual; ``` -### setURI +### contribute -*Sets account and loot token URI `metadata`.* +========================== TRIBUTE ========================== /// + +*Mints loot shares in exchange for tribute `amount` to an `account`. +If no `tribute` is set, then function will revert on `safeTransferFrom`.* ```solidity -function setURI(string calldata metadata) public virtual; +function contribute(address account, uint256 amount) public payable virtual; ``` -### setTimeValidity +### install -*Sets account ragequit time validity (or 'timespan').* +======================== INSTALLATION ======================== /// + +*Initializes ragequit settings for the caller account.* ```solidity -function setTimeValidity(uint48 validAfter, uint48 validUntil) public virtual; +function install(Ownership[] calldata owners, Settings calldata setting, Metadata calldata meta) + public + virtual; ``` ### getMetadata -============================ LOOT ============================ /// +==================== SETTINGS & METADATA ==================== /// *Returns the account metadata.* @@ -146,34 +162,52 @@ function getMetadata(address account) ### getSettings -*Returns the account ragequit time validity settings.* +*Returns the account tribute and ragequit time validity settings.* ```solidity -function getSettings(address account) public view virtual returns (uint48, uint48); +function getSettings(address account) public view virtual returns (address, uint48, uint48); ``` -### mint +### setAuth -*Mints loot shares for an owner of the caller account.* +*Sets new authority contract for the caller account.* ```solidity -function mint(address owner, uint96 shares) public payable virtual; +function setAuth(IAuth authority) public virtual; ``` -### burn +### setURI -*Burns loot shares from an owner of the caller account.* +*Sets account and loot token URI `metadata`.* + + +```solidity +function setURI(string calldata metadata) public virtual; +``` + +### setTimeValidity + +*Sets account ragequit time validity (or 'time window').* + + +```solidity +function setTimeValidity(uint48 validAfter, uint48 validUntil) public virtual; +``` + +### setTribute + +*Sets account contribution asset (tribute).* ```solidity -function burn(address owner, uint96 shares) public payable virtual; +function setTribute(address tribute) public virtual; ``` ### _balanceOf -=================== EXTERNAL TOKEN HELPERS =================== /// +=================== EXTERNAL ASSET HELPERS =================== /// *Returns the `amount` of ERC20 `token` owned by `account`. Returns zero if the `token` does not exist.* @@ -187,6 +221,15 @@ function _balanceOf(address token, address account) returns (uint256 amount); ``` +### _safeTransferETH + +*Sends `amount` (in wei) ETH to `to`.* + + +```solidity +function _safeTransferETH(address to, uint256 amount) internal virtual; +``` + ### _safeTransferFrom *Sends `amount` of ERC20 `token` from `from` to `to`.* @@ -217,7 +260,7 @@ function _beforeTokenTransfer(address from, address to, uint256 id, uint256 amou ### URI =========================== EVENTS =========================== /// -*Logs new loot metadata setting.* +*Logs new account loot metadata.* ```solidity @@ -225,33 +268,33 @@ event URI(string metadata, uint256 indexed id); ``` ### AuthSet -*Logs new authority contract for an account.* +*Logs new account authority contract.* ```solidity -event AuthSet(address indexed account, IAuth auth); +event AuthSet(address indexed account, IAuth authority); ``` -### TimeValiditySet -*Logs new account ragequit time validity setting.* +### TributeSet +*Logs new account contribution asset setting.* ```solidity -event TimeValiditySet(address indexed account, uint48 validAfter, uint48 validUntil); +event TributeSet(address indexed account, address tribute); ``` -## Errors -### TransferFromFailed -======================= CUSTOM ERRORS ======================= /// - -*The ERC20 `transferFrom` has failed.* +### TimeValiditySet +*Logs new account ragequit time validity setting.* ```solidity -error TransferFromFailed(); +event TimeValiditySet(address indexed account, uint48 validAfter, uint48 validUntil); ``` +## Errors ### InvalidTime +======================= CUSTOM ERRORS ======================= /// + *Invalid time window for ragequit.* @@ -260,6 +303,8 @@ error InvalidTime(); ``` ### InvalidAssetOrder +*Out-of-order redemption assets.* + ```solidity error InvalidAssetOrder(); @@ -273,11 +318,27 @@ error InvalidAssetOrder(); error MulDivFailed(); ``` +### TransferFromFailed +*ERC20 `transferFrom` failed.* + + +```solidity +error TransferFromFailed(); +``` + +### ETHTransferFailed +*ETH transfer failed.* + + +```solidity +error ETHTransferFailed(); +``` + ## Structs ### Metadata ========================== STRUCTS ========================== /// -*The account loot metadata struct.* +*The account loot shares metadata struct.* ```solidity @@ -291,7 +352,7 @@ struct Metadata { ``` ### Ownership -*The account loot shares struct.* +*The account loot shares ownership struct.* ```solidity @@ -302,11 +363,12 @@ struct Ownership { ``` ### Settings -*The account ragequit settings struct.* +*The account loot shares settings struct.* ```solidity struct Settings { + address tribute; uint48 validAfter; uint48 validUntil; } diff --git a/docs/src/src/Ragequitter.sol/interface.IAuth.md b/docs/src/src/Ragequitter.sol/interface.IAuth.md index eebf275..326e494 100644 --- a/docs/src/src/Ragequitter.sol/interface.IAuth.md +++ b/docs/src/src/Ragequitter.sol/interface.IAuth.md @@ -1,5 +1,5 @@ # IAuth -[Git Source](https://github.com/Moloch-Mystics/ragequit/blob/86d6dd99cf3f73cadf56ed6fdfbc85c29c7189ff/src/Ragequitter.sol) +[Git Source](https://github.com/Moloch-Mystics/ragequit/blob/ed98f5886956972c8e4422a029cd6053d14f537c/src/Ragequitter.sol) Simple authority interface for contracts. diff --git a/lib/solady b/lib/solady index f178f10..f20771a 160000 --- a/lib/solady +++ b/lib/solady @@ -1 +1 @@ -Subproject commit f178f103ce9f4153a8a9b5a90eedb346f3b537b6 +Subproject commit f20771a9688990cfd3065a288baccced010f4b56 diff --git a/src/Ragequitter.sol b/src/Ragequitter.sol index a4879e3..f11f765 100644 --- a/src/Ragequitter.sol +++ b/src/Ragequitter.sol @@ -105,6 +105,7 @@ contract Ragequitter is ERC6909 { if (block.timestamp < setting.validAfter) revert InvalidTime(); if (block.timestamp > setting.validUntil) revert InvalidTime(); + if (assets.length == 0) revert InvalidAssetOrder(); uint256 id = uint256(uint160(account)); uint256 supply = _metadata[id].totalSupply; @@ -115,12 +116,13 @@ contract Ragequitter is ERC6909 { address asset; address prev; + uint256 share; for (uint256 i; i != assets.length; ++i) { asset = assets[i]; if (asset <= prev) revert InvalidAssetOrder(); prev = asset; - uint256 share = _mulDiv(shares, _balanceOf(asset, account), supply); + share = _mulDiv(shares, _balanceOf(asset, account), supply); if (share != 0) _safeTransferFrom(asset, account, msg.sender, share); } } @@ -141,14 +143,14 @@ contract Ragequitter is ERC6909 { /// ============================ LOOT ============================ /// /// @dev Mints loot shares for an owner of the caller account. - function mint(address owner, uint96 shares) public payable virtual { + function mint(address owner, uint96 shares) public virtual { uint256 id = uint256(uint160(msg.sender)); _metadata[id].totalSupply += shares; _mint(owner, id, shares); } /// @dev Burns loot shares from an owner of the caller account. - function burn(address owner, uint96 shares) public payable virtual { + function burn(address owner, uint96 shares) public virtual { uint256 id = uint256(uint160(msg.sender)); unchecked { _metadata[id].totalSupply -= shares; @@ -218,8 +220,8 @@ contract Ragequitter is ERC6909 { } /// @dev Sets new authority contract for the caller account. - function setAuth(IAuth auth) public virtual { - emit AuthSet(msg.sender, (_metadata[uint256(uint160(msg.sender))].authority = auth)); + function setAuth(IAuth authority) public virtual { + emit AuthSet(msg.sender, (_metadata[uint256(uint160(msg.sender))].authority = authority)); } /// @dev Sets account and loot token URI `metadata`. @@ -228,10 +230,12 @@ contract Ragequitter is ERC6909 { emit URI((_metadata[id].tokenURI = metadata), id); } - /// @dev Sets account ragequit time validity (or 'timespan'). + /// @dev Sets account ragequit time validity (or 'time window'). function setTimeValidity(uint48 validAfter, uint48 validUntil) public virtual { emit TimeValiditySet( - msg.sender, _settings[msg.sender].validAfter, _settings[msg.sender].validUntil + msg.sender, + _settings[msg.sender].validAfter = validAfter, + _settings[msg.sender].validUntil = validUntil ); } @@ -309,8 +313,8 @@ contract Ragequitter is ERC6909 { virtual override(ERC6909) { - IAuth auth = _metadata[id].authority; - if (auth != IAuth(address(0))) auth.validateTransfer(from, to, id, amount); + IAuth authority = _metadata[id].authority; + if (authority != IAuth(address(0))) authority.validateTransfer(from, to, id, amount); } }