Skip to content

Commit

Permalink
async redeem
Browse files Browse the repository at this point in the history
  • Loading branch information
ungaro committed Dec 3, 2024
1 parent b3282d5 commit 3a4471f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 27 deletions.
26 changes: 7 additions & 19 deletions nest/src/token/pUSD.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/I
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import { ERC4626Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol";
import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
import { IERC20Metadata } from "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
Expand All @@ -29,14 +28,7 @@ import { ComponentToken } from "../ComponentToken.sol";
* @author Eugene Y. Q. Shen, Alp Guneysel
* @notice Unified Plume USD stablecoin
*/
contract pUSD is
Initializable,
ERC20Upgradeable,
AccessControlUpgradeable,
UUPSUpgradeable,
ReentrancyGuardUpgradeable,
ComponentToken
{
contract pUSD is Initializable, ERC20Upgradeable, AccessControlUpgradeable, UUPSUpgradeable, ComponentToken {

using SafeERC20 for IERC20;
using FixedPointMathLib for uint256;
Expand Down Expand Up @@ -132,9 +124,8 @@ contract pUSD is
__UUPSUpgradeable_init();
__AccessControl_init();
__ERC20_init("Plume USD", "pUSD");
__ReentrancyGuard_init();

super.initialize(owner, "Plume USD", "pUSD", asset_, false, false);
super.initialize(owner, "Plume USD", "pUSD", asset_, false, true);

pUSDStorage storage $ = _getpUSDStorage();
$.boringVault.teller = ITeller(teller_);
Expand Down Expand Up @@ -248,7 +239,7 @@ contract pUSD is
address receiver,
address controller,
uint256 minimumMint
) public virtual nonReentrant returns (uint256 shares) {
) public virtual returns (uint256 shares) {
if (receiver == address(0)) {
revert InvalidReceiver();
}
Expand Down Expand Up @@ -297,7 +288,7 @@ contract pUSD is
address controller,
uint256 price,
uint64 deadline
) public virtual nonReentrant returns (uint256) {
) public virtual returns (uint256) {
if (receiver == address(0)) {
revert InvalidReceiver();
}
Expand Down Expand Up @@ -345,7 +336,7 @@ contract pUSD is
uint256 shares,
address receiver,
address controller
) public virtual override(ComponentToken) nonReentrant returns (uint256 assets) {
) public virtual override(ComponentToken) returns (uint256 assets) {
// Check claimableRedeemRequest, Transfer assets to receiver, Clean up request state.
return super.redeem(shares, receiver, controller);
}
Expand Down Expand Up @@ -414,10 +405,7 @@ contract pUSD is
* @param amount Amount of tokens to transfer
* @return bool indicating whether the transfer was successful
*/
function transfer(
address to,
uint256 amount
) public virtual override(ERC20Upgradeable, IERC20) nonReentrant returns (bool) {
function transfer(address to, uint256 amount) public virtual override(ERC20Upgradeable, IERC20) returns (bool) {
address owner = msg.sender;
_transfer(owner, to, amount);
return true;
Expand All @@ -434,7 +422,7 @@ contract pUSD is
address from,
address to,
uint256 amount
) public virtual override(ERC20Upgradeable, IERC20) nonReentrant returns (bool) {
) public virtual override(ERC20Upgradeable, IERC20) returns (bool) {
address spender = msg.sender;
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
Expand Down
32 changes: 24 additions & 8 deletions nest/test/pUSD.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,17 @@ contract pUSDTest is Test {
);
token = pUSD(address(proxy));

vm.startPrank(owner);

// Grant ATOMIC_QUEUE_ROLE to mockAtomicQueue
bytes32 ATOMIC_QUEUE_ROLE = keccak256("ATOMIC_QUEUE_ROLE");
token.grantRole(ATOMIC_QUEUE_ROLE, address(mockAtomicQueue));

// Grant ADMIN_ROLE to mockAtomicQueue
token.grantRole(token.ADMIN_ROLE(), address(mockAtomicQueue));

vm.stopPrank();

// Setup balances
usdc.mint(user1, 1000e6);

Expand Down Expand Up @@ -193,25 +204,30 @@ contract pUSDTest is Test {
function testPreviewRedeem() public {
uint256 depositAmount = 100e6;
uint256 redeemAmount = 50e6;
uint256 price = 1e6;
uint64 deadline = uint64(block.timestamp + 1 hours);

// Setup: First deposit some tokens
vm.startPrank(user1);
token.deposit(depositAmount, user1, user1, 0);

// Request redemption
token.requestRedeem(redeemAmount, user1, user1, 1e6, deadline);

// Mock atomic queue fulfillment
vm.stopPrank();
vm.prank(address(mockAtomicQueue));
token.notifyRedeem(redeemAmount, redeemAmount, user1);

// Preview redeem should return same amount as assets (1:1 ratio)
uint256 expectedAssets = token.previewRedeem(redeemAmount);
assertEq(expectedAssets, redeemAmount);

// Verify actual redeem matches preview
// Mock the lens to return correct balance
mockLens.setBalance(user1, depositAmount);

// Request redemption
vm.prank(user1);
token.requestRedeem(redeemAmount, user1, user1, price, deadline);

// Simulate atomic queue fulfillment
vm.prank(address(mockAtomicQueue));
token.notifyRedeem(redeemAmount, redeemAmount, user1);

// Complete redemption
vm.prank(user1);
uint256 actualAssets = token.redeem(redeemAmount, user1, user1);

Expand Down

0 comments on commit 3a4471f

Please sign in to comment.