Skip to content

Commit

Permalink
rm snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
thedavidmeister committed Jan 5, 2025
1 parent 50dce8a commit 8ec62c1
Show file tree
Hide file tree
Showing 19 changed files with 57 additions and 161 deletions.
39 changes: 28 additions & 11 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,7 +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 {IReceiptVaultV2, IReceiptVaultV1} from "../interface/IReceiptVaultV2.sol";
import {IReceiptV2} from "../interface/IReceiptV2.sol";
import {IReceiptManagerV1} from "../interface/IReceiptManagerV1.sol";
import {
Expand Down Expand Up @@ -110,8 +109,8 @@ abstract contract ReceiptVault is
IReceiptManagerV1,
Multicall,
ReentrancyGuard,
ERC20Snapshot,
IReceiptVaultV1,
ERC20,
IReceiptVaultV2,
ICloneableV2
{
using LibFixedPointDecimalArithmeticOpenZeppelin for uint256;
Expand Down Expand Up @@ -150,23 +149,28 @@ abstract contract ReceiptVault is
__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() external view 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 @@ -657,13 +661,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
10 changes: 1 addition & 9 deletions src/concrete/vault/ERC20PriceOracleReceiptVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ 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);

Expand All @@ -113,14 +113,6 @@ contract ERC20PriceOracleReceiptVault is ReceiptVault {
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
19 changes: 0 additions & 19 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 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
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);
}
File renamed without changes.
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
29 changes: 0 additions & 29 deletions test/src/concrete/vault/OffchainAssetReceiptVault.roles.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ contract RolesTest is OffchainAssetReceiptVaultTest {
bytes32 handlerAdmin = vault.HANDLER_ADMIN();
bytes32 erc20TiererAdmin = vault.ERC20TIERER_ADMIN();
bytes32 erc1155TiererAdmin = vault.ERC1155TIERER_ADMIN();
bytes32 erc20SnapshotterAdmin = vault.ERC20SNAPSHOTTER_ADMIN();
bytes32 confiscatorAdmin = vault.CONFISCATOR_ADMIN();

assertTrue(vault.hasRole(depositorAdmin, alice));
Expand All @@ -38,7 +37,6 @@ contract RolesTest is OffchainAssetReceiptVaultTest {
assertTrue(vault.hasRole(handlerAdmin, alice));
assertTrue(vault.hasRole(erc20TiererAdmin, alice));
assertTrue(vault.hasRole(erc1155TiererAdmin, alice));
assertTrue(vault.hasRole(erc20SnapshotterAdmin, alice));
assertTrue(vault.hasRole(confiscatorAdmin, alice));
}

Expand Down Expand Up @@ -141,33 +139,6 @@ contract RolesTest is OffchainAssetReceiptVaultTest {
vault.setERC1155Tier(address(TierV2TestContract), minTier, context, data);
}

/// Test to checks snapshott without role
function testSnapshotWithoutRole(
uint256 fuzzedKeyAlice,
string memory assetName,
string memory assetSymbol,
bytes memory data
) external {
// Ensure the fuzzed key is within the valid range for secp256k1
fuzzedKeyAlice = bound(fuzzedKeyAlice, 1, SECP256K1_ORDER - 1);
address alice = vm.addr(fuzzedKeyAlice);
// Prank as Alice for the transaction
vm.startPrank(alice);
OffchainAssetReceiptVault vault = createVault(alice, assetName, assetSymbol);

string memory errorMessage = string(
abi.encodePacked(
"AccessControl: account ",
StringsUpgradeable.toHexString(alice),
" is missing role ",
vm.toString(vault.ERC20SNAPSHOTTER())
)
);
vm.expectRevert(bytes(errorMessage));
// Snapshot
vault.snapshot(data);
}

/// Test to checks Certify without role
function testCertifyWithoutRole(
uint256 fuzzedKeyAlice,
Expand Down
Loading

0 comments on commit 8ec62c1

Please sign in to comment.