Skip to content

Commit

Permalink
Add timelock parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
hieronx committed Aug 21, 2024
1 parent cf6775a commit 1ea70cc
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 7 deletions.
21 changes: 16 additions & 5 deletions src/TimelockedAsyncRedeem.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ import {ERC20} from "solmate/tokens/ERC20.sol";
*
* This Vault has the following properties:
* - yield for the underlying asset is assumed to be transferred directly into the vault by some arbitrary mechanism
* - async redemptions are subject to a 3 day delay
* - new redemptions restart the 3 day delay even if the prior redemption is claimable.
* - async redemptions are subject to a timelock
* - new redemptions restart the timelock even if the prior redemption is claimable.
* This can be resolved by using a more sophisticated algorithm for storing multiple requests.
* - the redemption exchange rate is locked in immediately upon request.
*/
abstract contract BaseTimelockedAsyncRedeem is BaseERC7540, IERC7540Redeem {
using FixedPointMathLib for uint256;

uint32 public constant TIMELOCK = 3 days;
uint32 public timelock;

uint256 internal _totalPendingRedeemAssets;
mapping(address => RedemptionRequest) internal _pendingRedemption;
Expand All @@ -33,6 +33,14 @@ abstract contract BaseTimelockedAsyncRedeem is BaseERC7540, IERC7540Redeem {
uint32 claimableTimestamp;
}

constructor(uint32 timelock_) {
timelock = timelock_;
}

function setTimelock(uint32 timelock_) public onlyOwner {
timelock = timelock_;
}

function totalAssets() public view virtual override returns (uint256) {
return ERC20(asset).balanceOf(address(this)) - _totalPendingRedeemAssets;
}
Expand All @@ -51,7 +59,7 @@ abstract contract BaseTimelockedAsyncRedeem is BaseERC7540, IERC7540Redeem {
SafeTransferLib.safeTransferFrom(this, owner, address(this), shares);

_pendingRedemption[controller] =
RedemptionRequest({assets: assets, shares: shares, claimableTimestamp: uint32(block.timestamp) + TIMELOCK});
RedemptionRequest({assets: assets, shares: shares, claimableTimestamp: uint32(block.timestamp) + timelock});

_totalPendingRedeemAssets += assets;

Expand Down Expand Up @@ -166,5 +174,8 @@ abstract contract BaseTimelockedAsyncRedeem is BaseERC7540, IERC7540Redeem {
}

contract TimelockedAsyncRedeem is BaseTimelockedAsyncRedeem {
constructor(ERC20 _asset, string memory _name, string memory _symbol) BaseERC7540(_asset, _name, _symbol) {}
constructor(uint32 timelock_, ERC20 _asset, string memory _name, string memory _symbol)
BaseTimelockedAsyncRedeem(timelock_)
BaseERC7540(_asset, _name, _symbol)
{}
}
2 changes: 1 addition & 1 deletion test/TestInterfaceFunctionSelectors.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ contract TestInterfaceFunctionSelectors is Test {

ERC20 asset = new USDC();
ControlledAsyncDeposit depositExample = new ControlledAsyncDeposit(asset, "Vault Share", "TEST");
TimelockedAsyncRedeem redeemExample = new TimelockedAsyncRedeem(asset, "Vault Share", "TEST");
TimelockedAsyncRedeem redeemExample = new TimelockedAsyncRedeem(3 days, asset, "Vault Share", "TEST");

assertTrue(depositExample.supportsInterface(erc7575Vault));
assertTrue(depositExample.supportsInterface(erc7540Operator));
Expand Down
2 changes: 1 addition & 1 deletion test/TimelockedAsyncRedeem.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ contract TimelockedAsyncRedeemTest is Test {
deal(address(asset), user, initialAssetBalance);

// Deploy the vault
vault = new TimelockedAsyncRedeem(asset, "Vault Share", "TEST");
vault = new TimelockedAsyncRedeem(3 days, asset, "Vault Share", "TEST");
shareToken = ERC20(address(vault));

// Deposit assets to the vault
Expand Down

0 comments on commit 1ea70cc

Please sign in to comment.