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

rm snapshot #214

Merged
merged 3 commits into from
Jan 6, 2025
Merged
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
359 changes: 178 additions & 181 deletions .gas-snapshot

Large diffs are not rendered by default.

52 changes: 34 additions & 18 deletions src/abstract/ReceiptVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd
pragma solidity =0.8.25;

import {ERC20SnapshotUpgradeable as ERC20Snapshot} from
"openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol";
import {ERC20Upgradeable as ERC20} from "openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol";
import {ReentrancyGuardUpgradeable as ReentrancyGuard} from
"openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol";
import {IERC20Upgradeable as IERC20} from
Expand All @@ -12,8 +11,7 @@ import {SafeERC20Upgradeable as SafeERC20} from
"openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/SafeERC20Upgradeable.sol";
import {MulticallUpgradeable as Multicall} from
"openzeppelin-contracts-upgradeable/contracts/utils/MulticallUpgradeable.sol";
import {IReceiptVaultV1} from "../interface/IReceiptVaultV1.sol";
import {IReceiptV2} from "../interface/IReceiptV2.sol";
import {IReceiptVaultV2, IReceiptVaultV1, IReceiptV2} from "../interface/IReceiptVaultV2.sol";
import {IReceiptManagerV1} from "../interface/IReceiptManagerV1.sol";
import {
LibFixedPointDecimalArithmeticOpenZeppelin,
Expand Down Expand Up @@ -110,8 +108,8 @@ abstract contract ReceiptVault is
IReceiptManagerV1,
Multicall,
ReentrancyGuard,
ERC20Snapshot,
IReceiptVaultV1,
ERC20,
IReceiptVaultV2,
ICloneableV2
{
using LibFixedPointDecimalArithmeticOpenZeppelin for uint256;
Expand Down Expand Up @@ -142,31 +140,36 @@ abstract contract ReceiptVault is
/// Deposits are payable so this allows refunds.
receive() external payable {}

/// Initialize the `ReceiptVault` and .
/// Initialize the `ReceiptVault`.
/// @param config All config required for initialization.
// solhint-disable-next-line func-name-mixedcase
// slither-disable-next-line naming-convention
function __ReceiptVault_init(VaultConfig memory config) internal virtual {
__Multicall_init();
__ReentrancyGuard_init();
__ERC20_init(config.name, config.symbol);
__ERC20Snapshot_init();
sAsset = IERC20(config.asset);

// Slither false positive here due to it being impossible to set the
// receipt before it has been deployed.
// slither-disable-next-line reentrancy-benign
IReceiptV2 receipt = IReceiptV2(iFactory.clone(address(iReceiptImplementation), abi.encode(address(this))));
sReceipt = receipt;
IReceiptV2 managedReceipt =
IReceiptV2(iFactory.clone(address(iReceiptImplementation), abi.encode(address(this))));
sReceipt = managedReceipt;

// Sanity check here. Should always be true as we cloned the receipt
// from the factory ourselves just above.
address receiptManager = receipt.manager();
address receiptManager = managedReceipt.manager();
if (receiptManager != address(this)) {
revert WrongManager(address(this), receiptManager);
}
}

/// @inheritdoc IReceiptVaultV2
function receipt() public view virtual returns (IReceiptV2) {
return sReceipt;
}

/// The spec demands this function ignores per-user concerns. It seems to
/// imply minting but doesn't provide a sibling conversion for burning.
/// > The amount of shares that the Vault would exchange for the amount of
Expand Down Expand Up @@ -516,7 +519,7 @@ abstract contract ReceiptVault is

// erc1155 mint.
// Receiving contracts MUST implement `IERC1155Receiver`.
sReceipt.managerMint(msg.sender, receiver, id, shares, receiptInformation);
receipt().managerMint(msg.sender, receiver, id, shares, receiptInformation);
}

/// Hook for additional actions that MUST complete or revert before deposit
Expand Down Expand Up @@ -544,7 +547,7 @@ abstract contract ReceiptVault is
// latter requires knowing the assets being withdrawn, which is what we
// are attempting to reverse engineer from the owner's receipt balance.
return _calculateRedeem(
sReceipt.balanceOf(owner, id),
receipt().balanceOf(owner, id),
// Assume the owner is hypothetically withdrawing for themselves.
_shareRatio(owner, owner, id, ShareAction.Burn)
);
Expand Down Expand Up @@ -623,22 +626,22 @@ abstract contract ReceiptVault is
// We additionally require that the sender is an operator of the
// receipt in order to burn the owner's shares.
// Same error message as Open Zeppelin ERC1155 implementation.
require(sReceipt.isApprovedForAll(owner, msg.sender), "ERC1155: caller is not token owner or approved");
require(receipt().isApprovedForAll(owner, msg.sender), "ERC1155: caller is not token owner or approved");
}

// ERC20 burn.
_burn(owner, shares);

// ERC1155 burn.
sReceipt.managerBurn(msg.sender, owner, id, shares, receiptInformation);
receipt().managerBurn(msg.sender, owner, id, shares, receiptInformation);

// Hook to allow additional withdrawal checks.
_afterWithdraw(assets, receiver, owner, shares, id);
}

/// @inheritdoc IReceiptVaultV1
function maxRedeem(address owner, uint256 id) external view virtual returns (uint256) {
return sReceipt.balanceOf(owner, id);
return receipt().balanceOf(owner, id);
}

/// @inheritdoc IReceiptVaultV1
Expand All @@ -657,13 +660,26 @@ abstract contract ReceiptVault is
return assets;
}

/// @inheritdoc ERC20Snapshot
/// @inheritdoc ERC20
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
}

function _afterWithdraw(uint256 assets, address receiver, address, uint256, uint256) internal virtual {
/// Hook that can be overridden/extended to add additional checks and
/// effects to the `withdraw` function. This hook is called after the shares
/// have been burned and the receipt has been burned. The default behaviour
/// is to transfer the assets to the receiver.
/// @param assets Amount of assets being withdrawn.
/// @param receiver Receiver of the withdrawn assets.
/// @param owner Owner of the shares being burned.
/// @param shares Amount of shares being burned.
/// @param id ID of the receipt being burned.
function _afterWithdraw(uint256 assets, address receiver, address owner, uint256 shares, uint256 id)
internal
virtual
{
// Default is to send assets after burning shares.
IERC20(asset()).safeTransfer(receiver, assets);
(owner, shares, id);
}
}
4 changes: 2 additions & 2 deletions src/concrete/receipt/Receipt.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {ICloneableV2, ICLONEABLE_V2_SUCCESS} from "rain.factory/interface/IClone

import {IReceiptManagerV1} from "../../interface/IReceiptManagerV1.sol";
import {IReceiptV2} from "../../interface/IReceiptV2.sol";
import {IReceiptVaultV1} from "../../interface/IReceiptVaultV1.sol";
import {IReceiptVaultV2} from "../../interface/IReceiptVaultV2.sol";
import {OnlyManager} from "../../error/ErrReceipt.sol";
import {ERC1155Upgradeable as ERC1155} from
"openzeppelin-contracts-upgradeable/contracts/token/ERC1155/ERC1155Upgradeable.sol";
Expand Down Expand Up @@ -101,7 +101,7 @@ contract Receipt is IReceiptV2, ERC1155, ICloneableV2 {
/// managing this `Receipt` is accepting for mints. Can be overridden if the
/// manager is not going to be a `ReceiptVault`.
function _vaultAssetSymbol() internal view virtual returns (string memory) {
return IERC20Metadata(IReceiptVaultV1(payable(address(sManager))).asset()).symbol();
return IERC20Metadata(IReceiptVaultV2(payable(address(sManager))).asset()).symbol();
}

/// @inheritdoc IReceiptV2
Expand Down
14 changes: 3 additions & 11 deletions src/concrete/vault/ERC20PriceOracleReceiptVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -93,34 +93,26 @@ contract ERC20PriceOracleReceiptVault is ReceiptVault {
constructor(ReceiptVaultConstructionConfig memory config) ReceiptVault(config) {}

/// Initialization of the underlying receipt vault and price oracle.
function initialize(bytes memory data) external override initializer returns (bytes32) {
function initialize(bytes memory data) external virtual override initializer returns (bytes32) {
ERC20PriceOracleVaultConfig memory config = abi.decode(data, (ERC20PriceOracleVaultConfig));
priceOracle = IPriceOracleV2(config.priceOracle);

__ReceiptVault_init(config.vaultConfig);

// Slither false positive due to needing sReceipt to be set so that the
// Slither false positive due to needing receipt to be set so that the
// event can be emitted with the correct data.
// slither-disable-next-line reentrancy-events
emit ERC20PriceOracleReceiptVaultInitialized(
msg.sender,
ERC20PriceOracleReceiptVaultConfig({
priceOracle: config.priceOracle,
receiptVaultConfig: ReceiptVaultConfig({receipt: address(sReceipt), vaultConfig: config.vaultConfig})
receiptVaultConfig: ReceiptVaultConfig({receipt: address(receipt()), vaultConfig: config.vaultConfig})
})
);

return ICLONEABLE_V2_SUCCESS;
}

/// Not strictly necessary as the receipt address is emitted during
/// initialization but this is a convenience getter for the receipt address.
/// It isn't in the `ReceiptVault` implementation because we need to keep the
/// base contract code size down.
function receipt() external view returns (address) {
return address(sReceipt);
}

/// The ID is the current oracle price always, even if this ID has already
/// been issued for some other receipt, it will simply result in multiple
/// holders of receipts with amounts of the same ID.
Expand Down
26 changes: 3 additions & 23 deletions src/concrete/vault/OffchainAssetReceiptVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,6 @@ contract OffchainAssetReceiptVault is ReceiptVault, AccessControl {
/// Rolename for ERC1155 tierer admins.
bytes32 public constant ERC1155TIERER_ADMIN = keccak256("ERC1155TIERER_ADMIN");

/// Rolename for ERC20 snapshotter.
/// ERC20 snapshotter role is required to snapshot shares.
bytes32 public constant ERC20SNAPSHOTTER = keccak256("ERC20SNAPSHOTTER");
/// Rolename for ERC20 snapshotter admins.
bytes32 public constant ERC20SNAPSHOTTER_ADMIN = keccak256("ERC20SNAPSHOTTER_ADMIN");

/// Rolename for ERC20 tierer.
/// ERC20 tierer role is required to modify the tier contract for shares.
bytes32 public constant ERC20TIERER = keccak256("ERC20TIERER");
Expand Down Expand Up @@ -297,9 +291,6 @@ contract OffchainAssetReceiptVault is ReceiptVault, AccessControl {
_setRoleAdmin(ERC1155TIERER, ERC1155TIERER_ADMIN);
_setRoleAdmin(ERC1155TIERER_ADMIN, ERC1155TIERER_ADMIN);

_setRoleAdmin(ERC20SNAPSHOTTER, ERC20SNAPSHOTTER_ADMIN);
_setRoleAdmin(ERC20SNAPSHOTTER_ADMIN, ERC20SNAPSHOTTER_ADMIN);

_setRoleAdmin(ERC20TIERER, ERC20TIERER_ADMIN);
_setRoleAdmin(ERC20TIERER_ADMIN, ERC20TIERER_ADMIN);

Expand All @@ -314,7 +305,6 @@ contract OffchainAssetReceiptVault is ReceiptVault, AccessControl {
_grantRole(CONFISCATOR_ADMIN, config.admin);
_grantRole(DEPOSITOR_ADMIN, config.admin);
_grantRole(ERC1155TIERER_ADMIN, config.admin);
_grantRole(ERC20SNAPSHOTTER_ADMIN, config.admin);
_grantRole(ERC20TIERER_ADMIN, config.admin);
_grantRole(HANDLER_ADMIN, config.admin);
_grantRole(WITHDRAWER_ADMIN, config.admin);
Expand All @@ -323,7 +313,7 @@ contract OffchainAssetReceiptVault is ReceiptVault, AccessControl {
msg.sender,
OffchainAssetReceiptVaultConfig({
admin: config.admin,
receiptVaultConfig: ReceiptVaultConfig({receipt: address(sReceipt), vaultConfig: config.vaultConfig})
receiptVaultConfig: ReceiptVaultConfig({receipt: address(receipt()), vaultConfig: config.vaultConfig})
})
);

Expand Down Expand Up @@ -424,15 +414,6 @@ contract OffchainAssetReceiptVault is ReceiptVault, AccessControl {
return shares_;
}

/// Exposes `ERC20Snapshot` from Open Zeppelin behind a role restricted call.
/// @param data_ Associated data relevant to the snapshot.
/// @return The snapshot ID as per Open Zeppelin.
function snapshot(bytes memory data_) external onlyRole(ERC20SNAPSHOTTER) returns (uint256) {
uint256 id_ = _snapshot();
emit SnapshotWithData(msg.sender, id_, data_);
return id_;
}

/// `ERC20TIERER` Role restricted setter for all internal state that drives
/// the erc20 tier restriction logic on transfers.
/// @param tier_ `ITier` contract to check when receiving shares. MAY be
Expand Down Expand Up @@ -706,11 +687,10 @@ contract OffchainAssetReceiptVault is ReceiptVault, AccessControl {
address(erc1155Tier) == address(0)
|| block.timestamp < erc1155Tier.reportTimeForTier(confiscatee, erc1155MinimumTier, erc1155TierContext)
) {
IReceiptV2 receipt = sReceipt;
confiscatedReceiptAmount = receipt.balanceOf(confiscatee, id);
confiscatedReceiptAmount = receipt().balanceOf(confiscatee, id);
if (confiscatedReceiptAmount > 0) {
emit ConfiscateReceipt(msg.sender, confiscatee, id, confiscatedReceiptAmount, data);
receipt.managerTransferFrom(confiscatee, msg.sender, id, confiscatedReceiptAmount, "");
receipt().managerTransferFrom(confiscatee, msg.sender, id, confiscatedReceiptAmount, "");
}
}
return confiscatedReceiptAmount;
Expand Down
15 changes: 15 additions & 0 deletions src/interface/IReceiptVaultV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: LicenseRef-DCL-1.0
// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd
pragma solidity ^0.8.0;

import {IReceiptVaultV1} from "./deprecated/IReceiptVaultV1.sol";
import {IReceiptV2} from "./IReceiptV2.sol";

/// @title IReceiptVaultV2
/// @notice The `IReceiptVaultV2` interface extends `IReceiptVaultV1` with a
/// getter for the `receipt` contract. Otherwise it is identical to
/// `IReceiptVaultV1`.
interface IReceiptVaultV2 is IReceiptVaultV1 {
/// @return The `IReceiptV2` contract that is the receipt for this vault.
function receipt() external view returns (IReceiptV2);
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ contract ERC20PriceOracleReceiptVaultConstructionTest is ERC20PriceOracleReceipt
assert(address(vault) != address(0));
assertEq(keccak256(bytes(vault.name())), keccak256(bytes(name)));
assertEq(keccak256(bytes(vault.symbol())), keccak256(bytes(symbol)));
assertEq(receiptAddress, vault.receipt());
assertEq(receiptAddress, address(vault.receipt()));
}

/// Test creating several different vaults
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from "rain.math.fixedpoint/lib/LibFixedPointDecimalArithmeticOpenZeppelin.sol";
import {IERC20} from "forge-std/interfaces/IERC20.sol";
import {Receipt as ReceiptContract} from "src/concrete/receipt/Receipt.sol";
import {IReceiptVaultV1} from "src/interface/IReceiptVaultV1.sol";
import {IReceiptVaultV2, IReceiptVaultV1} from "src/interface/IReceiptVaultV2.sol";
import {LibUniqueAddressesGenerator} from "../../../lib/LibUniqueAddressesGenerator.sol";
import {LibERC20PriceOracleReceiptVaultFork} from "../../../lib/LibERC20PriceOracleReceiptVaultFork.sol";
import {SFLR_CONTRACT} from "rain.flare/lib/sflr/LibSceptreStakedFlare.sol";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
Math
} from "rain.math.fixedpoint/lib/LibFixedPointDecimalArithmeticOpenZeppelin.sol";
import {IERC20} from "forge-std/interfaces/IERC20.sol";
import {IReceiptVaultV1} from "src/interface/IReceiptVaultV1.sol";
import {IReceiptVaultV2, IReceiptVaultV1} from "src/interface/IReceiptVaultV2.sol";
import {LibUniqueAddressesGenerator} from "../../../lib/LibUniqueAddressesGenerator.sol";

contract ERC20PriceOracleReceiptVaultreceiptVaultTest is ERC20PriceOracleReceiptVaultTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import {IERC20} from "forge-std/interfaces/IERC20.sol";
import {Receipt as ReceiptContract} from "src/concrete/receipt/Receipt.sol";
import {ZeroAssetsAmount, ZeroReceiver, ZeroOwner} from "src/abstract/ReceiptVault.sol";
import {IReceiptVaultV1} from "src/interface/IReceiptVaultV1.sol";
import {IReceiptVaultV2, IReceiptVaultV1} from "src/interface/IReceiptVaultV2.sol";
import {SFLR_CONTRACT} from "rain.flare/lib/sflr/LibSceptreStakedFlare.sol";
import {LibERC20PriceOracleReceiptVaultFork} from "../../../lib/LibERC20PriceOracleReceiptVaultFork.sol";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import {IERC20} from "forge-std/interfaces/IERC20.sol";
import {Receipt as ReceiptContract} from "src/concrete/receipt/Receipt.sol";
import {ZeroAssetsAmount, ZeroReceiver, ZeroOwner} from "src/abstract/ReceiptVault.sol";
import {IReceiptVaultV1} from "src/interface/IReceiptVaultV1.sol";
import {IReceiptVaultV2, IReceiptVaultV1} from "src/interface/IReceiptVaultV2.sol";
import {SFLR_CONTRACT} from "rain.flare/lib/sflr/LibSceptreStakedFlare.sol";
import {LibERC20PriceOracleReceiptVaultFork} from "../../../lib/LibERC20PriceOracleReceiptVaultFork.sol";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import {IReceiptV2} from "src/interface/IReceiptV2.sol";
import {OffchainAssetReceiptVaultTest, Vm} from "test/abstract/OffchainAssetReceiptVaultTest.sol";
import {LibOffchainAssetVaultCreator} from "test/lib/LibOffchainAssetVaultCreator.sol";
import {IReceiptVaultV1} from "src/interface/IReceiptVaultV1.sol";
import {IReceiptVaultV2, IReceiptVaultV1} from "src/interface/IReceiptVaultV2.sol";
import {LibUniqueAddressesGenerator} from "../../../lib/LibUniqueAddressesGenerator.sol";

contract CertifyTest is OffchainAssetReceiptVaultTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {MinShareRatio, ZeroAssetsAmount, ZeroReceiver} from "src/abstract/Receip
import {OffchainAssetReceiptVault, CertificationExpired} from "src/concrete/vault/OffchainAssetReceiptVault.sol";
import {OffchainAssetReceiptVaultTest, Vm} from "test/abstract/OffchainAssetReceiptVaultTest.sol";
import {LibOffchainAssetVaultCreator} from "test/lib/LibOffchainAssetVaultCreator.sol";
import {IReceiptVaultV1} from "src/interface/IReceiptVaultV1.sol";
import {IReceiptVaultV2, IReceiptVaultV1} from "src/interface/IReceiptVaultV2.sol";
import {LibUniqueAddressesGenerator} from "../../../lib/LibUniqueAddressesGenerator.sol";

contract OffchainAssetReceiptVaultDepositTest is OffchainAssetReceiptVaultTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {MinShareRatio, ZeroAssetsAmount, ZeroReceiver} from "src/abstract/Receip
import {OffchainAssetReceiptVault, CertificationExpired} from "src/concrete/vault/OffchainAssetReceiptVault.sol";
import {OffchainAssetReceiptVaultTest, Vm} from "test/abstract/OffchainAssetReceiptVaultTest.sol";
import {LibOffchainAssetVaultCreator} from "test/lib/LibOffchainAssetVaultCreator.sol";
import {IReceiptVaultV1} from "src/interface/IReceiptVaultV1.sol";
import {IReceiptVaultV2, IReceiptVaultV1} from "src/interface/IReceiptVaultV2.sol";
import {IReceiptV2} from "src/interface/IReceiptV2.sol";
import {LibUniqueAddressesGenerator} from "../../../lib/LibUniqueAddressesGenerator.sol";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
LibFixedPointDecimalArithmeticOpenZeppelin,
Math
} from "rain.math.fixedpoint/lib/LibFixedPointDecimalArithmeticOpenZeppelin.sol";
import {IReceiptVaultV1} from "src/interface/IReceiptVaultV1.sol";
import {IReceiptVaultV2, IReceiptVaultV1} from "src/interface/IReceiptVaultV2.sol";
import {LibUniqueAddressesGenerator} from "../../../lib/LibUniqueAddressesGenerator.sol";

contract RedeemTest is OffchainAssetReceiptVaultTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Math
} from "rain.math.fixedpoint/lib/LibFixedPointDecimalArithmeticOpenZeppelin.sol";
import {LibOffchainAssetVaultCreator} from "test/lib/LibOffchainAssetVaultCreator.sol";
import {IReceiptVaultV1} from "src/interface/IReceiptVaultV1.sol";
import {IReceiptVaultV2, IReceiptVaultV1} from "src/interface/IReceiptVaultV2.sol";
import {LibUniqueAddressesGenerator} from "../../../lib/LibUniqueAddressesGenerator.sol";

contract RedepositTest is OffchainAssetReceiptVaultTest {
Expand Down
Loading
Loading