-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
112 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
@openzeppelin-5.1.0/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ | ||
@openzeppelin-5.1.0/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ | ||
@solady-0.0.268/=lib/solady/src/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import {ERC20} from "@solady-0.0.268/tokens/ERC20.sol"; | ||
|
||
|
||
|
||
// TODO: use DepositInfo struct | ||
|
||
// struct DepositInfo { | ||
// uint256 amount; | ||
// address depositor; | ||
// uint64 redeemTimestamp; | ||
// } | ||
|
||
interface IEntrypoint { | ||
function deposit(address sender, address receiver, uint256 amount) external returns (uint256 shares); | ||
function withdraw(uint256 amount, address receiver, address owner) external returns (uint256 shares); | ||
function convertToShares(uint256 assets) external view returns (uint256 shares); | ||
function convertToAssets(uint256 shares) external view returns (uint256 assets); | ||
function share() external view returns (address); | ||
function asset() external view returns (address); | ||
} | ||
|
||
contract LockedAssetEntrypoint is IEntrypoint { | ||
address public immutable shareToken; | ||
address public immutable assetToken; | ||
uint256 public immutable lockPeriod; | ||
|
||
|
||
// unlimited deposits | ||
uint256 public immutable maxDeposit = type(uint256).max; | ||
|
||
mapping(address => uint256) private balances; | ||
mapping(address => uint256) private lockExpiry; | ||
|
||
event Deposit(address indexed from, address indexed to, uint256 assets, uint256 shares); | ||
event Withdraw(address indexed from, address indexed to, address indexed owner, uint256 assets, uint256 shares); | ||
|
||
constructor(address _shareToken, address _assetToken, uint256 _lockPeriod) { | ||
shareToken = _shareToken; | ||
assetToken = _assetToken; | ||
lockPeriod = _lockPeriod; | ||
} | ||
|
||
modifier afterLockPeriod(address user) { | ||
require(block.timestamp >= lockExpiry[user], "Assets are locked"); | ||
_; | ||
} | ||
|
||
function deposit(address sender, address receiver, uint256 amount) external override returns (uint256 shares) { | ||
require(amount > 0, "Amount must be greater than zero"); | ||
// NOTE: sender must have approved the asset token transfer to this contract | ||
ERC20(assetToken).transferFrom(sender, address(this), amount); | ||
shares = convertToShares(amount); | ||
balances[receiver] += shares; | ||
lockExpiry[receiver] = block.timestamp + lockPeriod; | ||
ERC20(shareToken).transfer(receiver, shares); | ||
emit Deposit(sender, receiver, amount, shares); | ||
} | ||
|
||
function withdraw(uint256 amount, address receiver, address owner) | ||
external | ||
override | ||
afterLockPeriod(owner) | ||
returns (uint256 shares) | ||
{ | ||
shares = convertToShares(amount); | ||
require(balances[owner] >= shares, "Insufficient shares"); | ||
|
||
balances[owner] -= shares; | ||
|
||
ERC20(shareToken).transferFrom(owner, address(this), shares); | ||
ERC20(assetToken).transfer(receiver, amount); | ||
|
||
emit Withdraw(msg.sender, receiver, owner, amount, shares); | ||
} | ||
|
||
function convertToShares(uint256 assets) public pure override returns (uint256 shares) { | ||
return assets; | ||
} | ||
|
||
function convertToAssets(uint256 shares) public pure override returns (uint256 assets) { | ||
return shares; | ||
} | ||
|
||
function share() external view override returns (address) { | ||
return shareToken; | ||
} | ||
|
||
function asset() external view override returns (address) { | ||
return assetToken; | ||
} | ||
|
||
function balanceOf(address user) external view returns (uint256) { | ||
return balances[user]; | ||
} | ||
|
||
function lockExpiryOf(address user) external view returns (uint256) { | ||
return lockExpiry[user]; | ||
} | ||
} |