-
Notifications
You must be signed in to change notification settings - Fork 48
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
Add token wrapper #526
base: develop
Are you sure you want to change the base?
Add token wrapper #526
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// SPDX-License-Identifier: MIT | ||
// Disclaimer https://github.com/hats-finance/hats-contracts/blob/main/DISCLAIMER.md | ||
|
||
pragma solidity 0.8.16; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; | ||
|
||
contract HATTokenWrapper is ERC4626 { | ||
|
||
error AmountOfSharesMustBeMoreThanMinimalAmount(); | ||
|
||
uint256 public constant MINIMAL_AMOUNT_OF_SHARES = 1e3; // to reduce rounding errors, the number of shares is either 0, or > than this number | ||
|
||
constructor (IERC20 _asset, string memory _name, string memory _symbol) ERC4626(_asset) ERC20(_name, _symbol) {} | ||
|
||
function _afterTokenTransfer(address, address, uint256) internal virtual override { | ||
if (totalSupply() > 0 && totalSupply() < MINIMAL_AMOUNT_OF_SHARES) { | ||
revert AmountOfSharesMustBeMoreThanMinimalAmount(); | ||
} | ||
} | ||
|
||
} | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,9 +2,8 @@ | |
pragma solidity 0.8.16; | ||
|
||
import "@openzeppelin/contracts/governance/utils/IVotes.sol"; | ||
import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol"; | ||
|
||
interface IHATToken is IVotes, IERC20Permit { | ||
interface IHATToken is IVotes { | ||
Comment on lines
5
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The - interface IHATToken is IVotes {
+ interface IHATToken is IVotes, IERC20Permit { |
||
|
||
// Amount for minting or burning cannot be zero | ||
error ZeroAmount(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -190,7 +190,7 @@ function executeBatch(address[] targets, uint256[] values, bytes[] payloads, byt | |
### getMinDelay | ||
|
||
```solidity | ||
function getMinDelay() external view returns (uint256 duration) | ||
function getMinDelay() external view returns (uint256) | ||
``` | ||
|
||
|
||
|
@@ -202,7 +202,7 @@ function getMinDelay() external view returns (uint256 duration) | |
|
||
| Name | Type | Description | | ||
|---|---|---| | ||
| duration | uint256 | undefined | | ||
| _0 | uint256 | undefined | | ||
|
||
### getRoleAdmin | ||
|
||
|
@@ -229,12 +229,12 @@ function getRoleAdmin(bytes32 role) external view returns (bytes32) | |
### getTimestamp | ||
|
||
```solidity | ||
function getTimestamp(bytes32 id) external view returns (uint256 timestamp) | ||
function getTimestamp(bytes32 id) external view returns (uint256) | ||
``` | ||
|
||
|
||
|
||
*Returns the timestamp at with an operation becomes ready (0 for unset operations, 1 for done operations).* | ||
*Returns the timestamp at which an operation becomes ready (0 for unset operations, 1 for done operations).* | ||
|
||
#### Parameters | ||
|
||
|
@@ -246,7 +246,7 @@ function getTimestamp(bytes32 id) external view returns (uint256 timestamp) | |
|
||
| Name | Type | Description | | ||
|---|---|---| | ||
| timestamp | uint256 | undefined | | ||
| _0 | uint256 | undefined | | ||
|
||
### grantRole | ||
|
||
|
@@ -291,7 +291,7 @@ function hasRole(bytes32 role, address account) external view returns (bool) | |
### hashOperation | ||
|
||
```solidity | ||
function hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) external pure returns (bytes32 hash) | ||
function hashOperation(address target, uint256 value, bytes data, bytes32 predecessor, bytes32 salt) external pure returns (bytes32) | ||
``` | ||
|
||
|
||
|
@@ -312,12 +312,12 @@ function hashOperation(address target, uint256 value, bytes data, bytes32 predec | |
|
||
| Name | Type | Description | | ||
|---|---|---| | ||
| hash | bytes32 | undefined | | ||
| _0 | bytes32 | undefined | | ||
|
||
### hashOperationBatch | ||
|
||
```solidity | ||
function hashOperationBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) external pure returns (bytes32 hash) | ||
function hashOperationBatch(address[] targets, uint256[] values, bytes[] payloads, bytes32 predecessor, bytes32 salt) external pure returns (bytes32) | ||
``` | ||
|
||
|
||
|
@@ -338,12 +338,12 @@ function hashOperationBatch(address[] targets, uint256[] values, bytes[] payload | |
|
||
| Name | Type | Description | | ||
|---|---|---| | ||
| hash | bytes32 | undefined | | ||
| _0 | bytes32 | undefined | | ||
|
||
### isOperation | ||
|
||
```solidity | ||
function isOperation(bytes32 id) external view returns (bool registered) | ||
function isOperation(bytes32 id) external view returns (bool) | ||
``` | ||
|
||
|
||
|
@@ -360,12 +360,12 @@ function isOperation(bytes32 id) external view returns (bool registered) | |
|
||
| Name | Type | Description | | ||
|---|---|---| | ||
| registered | bool | undefined | | ||
| _0 | bool | undefined | | ||
|
||
### isOperationDone | ||
|
||
```solidity | ||
function isOperationDone(bytes32 id) external view returns (bool done) | ||
function isOperationDone(bytes32 id) external view returns (bool) | ||
``` | ||
|
||
|
||
|
@@ -382,17 +382,17 @@ function isOperationDone(bytes32 id) external view returns (bool done) | |
|
||
| Name | Type | Description | | ||
|---|---|---| | ||
| done | bool | undefined | | ||
| _0 | bool | undefined | | ||
|
||
### isOperationPending | ||
|
||
```solidity | ||
function isOperationPending(bytes32 id) external view returns (bool pending) | ||
function isOperationPending(bytes32 id) external view returns (bool) | ||
``` | ||
|
||
|
||
|
||
*Returns whether an operation is pending or not.* | ||
*Returns whether an operation is pending or not. Note that a "pending" operation may also be "ready".* | ||
|
||
#### Parameters | ||
|
||
|
@@ -404,17 +404,17 @@ function isOperationPending(bytes32 id) external view returns (bool pending) | |
|
||
| Name | Type | Description | | ||
|---|---|---| | ||
| pending | bool | undefined | | ||
| _0 | bool | undefined | | ||
|
||
### isOperationReady | ||
|
||
```solidity | ||
function isOperationReady(bytes32 id) external view returns (bool ready) | ||
function isOperationReady(bytes32 id) external view returns (bool) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The return type of the - function isOperationReady(bytes32 id) external view returns (bool)
+ // Returns true if the operation is ready, false otherwise
+ function isOperationReady(bytes32 id) external view returns (bool ready) |
||
``` | ||
|
||
|
||
|
||
*Returns whether an operation is ready or not.* | ||
*Returns whether an operation is ready for execution. Note that a "ready" operation is also "pending".* | ||
|
||
#### Parameters | ||
|
||
|
@@ -426,7 +426,7 @@ function isOperationReady(bytes32 id) external view returns (bool ready) | |
|
||
| Name | Type | Description | | ||
|---|---|---| | ||
| ready | bool | undefined | | ||
| _0 | bool | undefined | | ||
|
||
### onERC1155BatchReceived | ||
|
||
|
@@ -547,7 +547,7 @@ function schedule(address target, uint256 value, bytes data, bytes32 predecessor | |
|
||
|
||
|
||
*Schedule an operation containing a single transaction. Emits a {CallScheduled} event. Requirements: - the caller must have the 'proposer' role.* | ||
*Schedule an operation containing a single transaction. Emits {CallSalt} if salt is nonzero, and {CallScheduled}. Requirements: - the caller must have the 'proposer' role.* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
#### Parameters | ||
|
||
|
@@ -568,7 +568,7 @@ function scheduleBatch(address[] targets, uint256[] values, bytes[] payloads, by | |
|
||
|
||
|
||
*Schedule an operation containing a batch of transactions. Emits one {CallScheduled} event per transaction in the batch. Requirements: - the caller must have the 'proposer' role.* | ||
*Schedule an operation containing a batch of transactions. Emits {CallSalt} if salt is nonzero, and one {CallScheduled} event per transaction in the batch. Requirements: - the caller must have the 'proposer' role.* | ||
|
||
#### Parameters | ||
|
||
|
@@ -767,6 +767,23 @@ event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, ui | |
| value | uint256 | undefined | | ||
| data | bytes | undefined | | ||
|
||
### CallSalt | ||
|
||
```solidity | ||
event CallSalt(bytes32 indexed id, bytes32 salt) | ||
``` | ||
|
||
|
||
|
||
|
||
|
||
#### Parameters | ||
|
||
| Name | Type | Description | | ||
|---|---|---| | ||
| id `indexed` | bytes32 | undefined | | ||
| salt | bytes32 | undefined | | ||
|
||
Comment on lines
+773
to
+786
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A new event + // Emitted when an operation with a non-zero salt is scheduled
+ event CallSalt(bytes32 indexed id, bytes32 salt) |
||
### CallScheduled | ||
|
||
```solidity | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CodeRabbit
The
HATTokenWrapper
contract seems to be well implemented. It correctly extends theERC4626
contract from OpenZeppelin and overrides the_afterTokenTransfer
function to enforce a minimum amount of shares. The use of custom error types for revert reasons is also a good practice as it can make debugging easier. However, there's a minor issue with the constructor. It should call the parent constructors in the correct order.