Skip to content
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

[PDE-683] fix compilation issues for AssetToken / YieldToken #157

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@
[submodule "nest/lib/nucleus-boring-vault"]
path = nest/lib/nucleus-boring-vault
url = https://github.com/plumenetwork/nucleus-boring-vault
[submodule "smart-wallets/lib/solmate"]
path = smart-wallets/lib/solmate
url = https://github.com/transmissions11/solmate
5 changes: 0 additions & 5 deletions smart-wallets/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,3 @@ int_types = "long"
quote_style = "double"
number_underscore = "thousands"
wrap_comments = true

remappings = [
"@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
]
1 change: 1 addition & 0 deletions smart-wallets/lib/solmate
Submodule solmate added at c93f77
3 changes: 3 additions & 0 deletions smart-wallets/remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
@solmate/=lib/solmate/src/
16 changes: 8 additions & 8 deletions smart-wallets/script/DeployAssetToken.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ contract DeployAssetToken is Script, Test {
address private constant ADMIN_ADDRESS = 0xb015762405De8fD24d29A6e0799c12e0Ea81c1Ff;

// Address of the currency token
// pUSD in Plume Mainnet
address private constant CURRENCY_TOKEN_ADDRESS = 0xdddD73F5Df1F0DC31373357beAC77545dC5A6f3F;
// USDC in Plume Mainnet
address private constant CURRENCY_TOKEN_ADDRESS = 0x3938A812c54304fEffD266C7E2E70B48F9475aD6;

function test() public { }

Expand All @@ -28,16 +28,16 @@ contract DeployAssetToken is Script, Test {
AssetTokenProxy assetTokenProxy = new AssetTokenProxy(
address(assetToken),
abi.encodeCall(
assetTokenProxy.initialize,
assetToken.initialize,
(
ADMIN_ADDRESS, // owner
"Real World Asset Token", // name
"RWA", // symbol
"Mineral Vault I Security Token", // name
"aMNRL", // symbol
ERC20(CURRENCY_TOKEN_ADDRESS), // currencyToken
18, // decimals
"https://metadata.uri", // tokenURI
1000e18, // initialSupply
1_000_000e18, // totalValue
"https://mineralvault.io/metadata/aMNRL.json", // tokenURI
1_000_000e18, // initialSupply
10_000_000e18, // totalValue
false // isWhitelistEnabled
)
)
Expand Down
12 changes: 6 additions & 6 deletions smart-wallets/script/DeployYieldToken.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ contract DeployYieldToken is Script, Test {

// Change these addresses
address private constant ADMIN_ADDRESS = 0xb015762405De8fD24d29A6e0799c12e0Ea81c1Ff;
address private constant CURRENCY_TOKEN_ADDRESS = 0xdddD73F5Df1F0DC31373357beAC77545dC5A6f3F;
address private constant ASSET_TOKEN_ADDRESS = 0x659619AEdf381c3739B0375082C2d61eC1fD8835;
address private constant CURRENCY_TOKEN_ADDRESS = 0x3938A812c54304fEffD266C7E2E70B48F9475aD6;
address private constant ASSET_TOKEN_ADDRESS = 0x2Ac2227eaD821F0499798AC844924F49CB9cFD90;

function test() public { }

Expand All @@ -30,13 +30,13 @@ contract DeployYieldToken is Script, Test {
yieldToken.initialize,
(
ADMIN_ADDRESS,
"Yield Token",
"YLD",
"Mineral Vault I Yield Token",
"yMNRL",
IERC20(CURRENCY_TOKEN_ADDRESS),
18,
"https://metadata.uri",
"https://mineralvault.io/metadata/yMNRL.json",
IAssetToken(ASSET_TOKEN_ADDRESS),
1000e18
1_000_000e18
)
)
);
Expand Down
23 changes: 19 additions & 4 deletions smart-wallets/script/UpgradeAssetToken.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
pragma solidity ^0.8.25;

import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { Script } from "forge-std/Script.sol";
import { Test } from "forge-std/Test.sol";
import { console2 } from "forge-std/console2.sol";
Expand All @@ -10,12 +12,15 @@ import { AssetToken } from "../src/token/AssetToken.sol";

contract UpgradeAssetToken is Script, Test {

uint8 constant VERSION = 2; // Increment this from previous version

// Address of the admin
address private constant ADMIN_ADDRESS = 0xb015762405De8fD24d29A6e0799c12e0Ea81c1Ff;
address private constant CURRENCY_TOKEN_ADDRESS = 0x3938A812c54304fEffD266C7E2E70B48F9475aD6;

// Address of the deployed AssetToken proxy
UUPSUpgradeable private constant ASSET_TOKEN_PROXY =
UUPSUpgradeable(payable(0x659619AEdf381c3739B0375082C2d61eC1fD8835));
UUPSUpgradeable(payable(0x2Ac2227eaD821F0499798AC844924F49CB9cFD90));

function test() public { }

Expand All @@ -29,10 +34,20 @@ contract UpgradeAssetToken is Script, Test {

// Upgrade to new implementation
ASSET_TOKEN_PROXY.upgradeToAndCall(address(newAssetTokenImpl), "");
console2.log("AssetToken proxy upgraded to new implementation");

// Get the upgraded contract instance
AssetToken assetToken = AssetToken(address(ASSET_TOKEN_PROXY));
/*
AssetToken(address(ASSET_TOKEN_PROXY)).reinitialize(
VERSION,
"Mineral Vault I Security Token", // name
"aMNRL", // symbol
"https://arc.plumenetwork.xyz/metadata/mineral-vault.json", // tokenURI
CURRENCY_TOKEN_ADDRESS, // newCurrencyToken
18, // decimals
10_000_000e18, // totalValue
false // isWhitelistEnabled
);
*/
console2.log("AssetToken proxy upgraded to new implementation");

console2.log("Upgrade complete. Proxy address:", address(ASSET_TOKEN_PROXY));

Expand Down
88 changes: 88 additions & 0 deletions smart-wallets/src/token/AssetToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,44 @@ contract AssetToken is
_mint(owner, initialSupply);
}

/**
* @notice Reinitialize the AssetToken with updated parameters
* @dev This function can be called multiple times, but only by the owner and with increasing version numbers
* @param version Version number for the reinitialization
* @param newName Optional new name for the token (empty string to keep current)
* @param newSymbol Optional new symbol for the token (empty string to keep current)
* @param newTokenURI Optional new token URI (empty string to keep current)
* @param newCurrencyToken Optional new currency token (address(0) to keep current)
* @param newDecimals Optional new decimals (0 to keep current)
* @param newTotalValue Optional new total value (0 to keep current)
* @param newWhitelistEnabled Optional new whitelist enabled setting
*/
function reinitialize(
uint8 version,
string memory newName,
string memory newSymbol,
string memory newTokenURI,
address newCurrencyToken,
uint8 newDecimals,
uint256 newTotalValue,
bool newWhitelistEnabled
) public reinitializer(version) onlyRole(ADMIN_ROLE) {
// Reinitialize YieldDistributionToken
__YieldDistributionToken_reinitialize(
version, newName, newSymbol, IERC20(newCurrencyToken), newDecimals, newTokenURI
);

AssetTokenStorage storage $ = _getAssetTokenStorage();

// Update total value if provided
if (newTotalValue > 0) {
$.totalValue = newTotalValue;
}

// Update whitelist setting
$.isWhitelistEnabled = newWhitelistEnabled;
}

// Override Functions

/**
Expand Down Expand Up @@ -350,4 +388,54 @@ contract AssetToken is
}
}

function getYieldCalculationState(
address user
)
external
view
returns (
uint256 userBalance,
uint256 lastUpdateTimestamp,
uint256 timeSinceLastUpdate,
uint256 userAmountSeconds,
uint256 yieldPerTokenStored,
uint256 userYieldPerTokenPaid,
uint256 yieldDifference,
uint256 currentRewards,
uint256 contractBalance
)
{
YieldDistributionTokenStorage storage $ = _getYieldDistributionTokenStorage();

userBalance = balanceOf(user);
lastUpdateTimestamp = $.lastUpdate[user];
timeSinceLastUpdate = block.timestamp - lastUpdateTimestamp;
userAmountSeconds = userBalance * timeSinceLastUpdate;
yieldPerTokenStored = $.yieldPerTokenStored;
userYieldPerTokenPaid = $.userYieldPerTokenPaid[user];
yieldDifference = yieldPerTokenStored - userYieldPerTokenPaid;
currentRewards = $.rewards[user];
contractBalance = $.currencyToken.balanceOf(address(this));
}

function getGlobalState()
external
view
returns (
uint256 totalSupply_,
uint256 totalAmountSeconds_,
uint256 lastSupplyUpdate_,
uint256 lastDepositTimestamp_,
uint256 yieldPerTokenStored_
)
{
YieldDistributionTokenStorage storage $ = _getYieldDistributionTokenStorage();

totalSupply_ = totalSupply();
totalAmountSeconds_ = $.totalAmountSeconds;
lastSupplyUpdate_ = $.lastSupplyUpdate;
lastDepositTimestamp_ = $.lastDepositTimestamp;
yieldPerTokenStored_ = $.yieldPerTokenStored;
}

}
11 changes: 4 additions & 7 deletions smart-wallets/src/token/YieldDistributionToken.sol
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

import { IYieldDistributionToken } from "../interfaces/IYieldDistributionToken.sol";
import { AccessControlUpgradeable } from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";

import { IYieldDistributionToken } from "../interfaces/IYieldDistributionToken.sol";

/**
* @title YieldDistributionToken
* @author Eugene Y. Q. Shen, Alp Guneysel
Expand All @@ -20,7 +18,7 @@ import { IYieldDistributionToken } from "../interfaces/IYieldDistributionToken.s
abstract contract YieldDistributionToken is
Initializable,
ERC20Upgradeable,
OwnableUpgradeable,
AccessControlUpgradeable,
IYieldDistributionToken
{

Expand Down Expand Up @@ -106,7 +104,6 @@ abstract contract YieldDistributionToken is
string memory tokenURI_
) internal onlyInitializing {
__ERC20_init(name, symbol);
__Ownable_init(owner);

_grantRole(DEFAULT_ADMIN_ROLE, owner);
_grantRole(ADMIN_ROLE, owner);
Expand Down Expand Up @@ -275,7 +272,7 @@ abstract contract YieldDistributionToken is
*/
function setTokenURI(
string memory tokenURI
) external onlyOwner {
) external onlyRole(ADMIN_ROLE) {
_getYieldDistributionTokenStorage().tokenURI = tokenURI;
}

Expand Down
35 changes: 13 additions & 22 deletions smart-wallets/src/token/YieldToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ERC4626Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ER
import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import { IERC4626 } from "@openzeppelin/contracts/interfaces/IERC4626.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { FixedPointMathLib } from "@solmate/utils/FixedPointMathLib.sol";

import { WalletUtils } from "../WalletUtils.sol";
import { IAssetToken } from "../interfaces/IAssetToken.sol";
Expand Down Expand Up @@ -36,6 +37,7 @@ contract YieldToken is
IComponentToken
{

using FixedPointMathLib for uint256;
// Storage

/// @custom:storage-location erc7201:plume.storage.YieldToken
Expand Down Expand Up @@ -278,7 +280,12 @@ contract YieldToken is
}

/// @inheritdoc IERC4626
function totalAssets() public view override(ERC4626, IComponentToken) returns (uint256 totalManagedAssets) {
function totalAssets()
public
view
override(ERC4626Upgradeable, IComponentToken)
returns (uint256 totalManagedAssets)
{
YieldTokenStorage storage $ = _getYieldTokenStorage();
return $.totalManagedAssets;
}
Expand Down Expand Up @@ -319,11 +326,6 @@ contract YieldToken is
return (shares * totalAssets()) / supply;
}

/// @inheritdoc ERC20Upgradeable
function decimals() public view override(YieldDistributionToken, ERC4626Upgradeable) returns (uint8) {
return super.decimals();
}

/// @inheritdoc ERC20Upgradeable
function _update(
address from,
Expand All @@ -347,6 +349,8 @@ contract YieldToken is
IERC20 currencyToken,
uint256 currencyTokenAmount
) external nonReentrant {
YieldTokenStorage storage $ = _getYieldTokenStorage();

if (assetToken != _getYieldTokenStorage().assetToken) {
revert InvalidAssetToken(assetToken, _getYieldTokenStorage().assetToken);
}
Expand All @@ -355,7 +359,7 @@ contract YieldToken is
}

_depositYield(currencyTokenAmount);
$.yieldBuffer += amount;
$.yieldBuffer += currencyTokenAmount;
}

/// @inheritdoc IComponentToken
Expand Down Expand Up @@ -687,24 +691,11 @@ contract YieldToken is
}

// Explicitly override decimals to use YieldDistributionToken's implementation
function decimals() public view override(YieldDistributionToken, ERC4626) returns (uint8) {
function decimals() public view override(YieldDistributionToken, ERC4626Upgradeable) returns (uint8) {
return YieldDistributionToken.decimals();
}

// Disable direct ERC4626 deposit/mint/withdraw/redeem functions
function deposit(uint256, address, address) public override(ERC4626) returns (uint256) {
revert Unimplemented();
}

function mint(uint256, address) public override(ERC4626) returns (uint256) {
revert Unimplemented();
}

function withdraw(uint256, address, address) public override(ERC4626) returns (uint256) {
revert Unimplemented();
}

function redeem(uint256, address, address) public override(ERC4626) returns (uint256) {
function mint(uint256, address) public override(ERC4626Upgradeable) returns (uint256) {
revert Unimplemented();
}

Expand Down
Loading
Loading