Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into convert-erc20priceora…
Browse files Browse the repository at this point in the history
…clereceiptvault-baseredeem
  • Loading branch information
ninokeldishvili committed Jul 10, 2024
2 parents b635b98 + 51398ff commit 75b48e4
Show file tree
Hide file tree
Showing 8 changed files with 474 additions and 1,774 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// SPDX-License-Identifier: CAL
pragma solidity =0.8.25;

import {ReceiptVaultConfig, VaultConfig} from "../../../../../contracts/abstract/ReceiptVault.sol";
import {
ERC20PriceOracleReceiptVault,
ERC20PriceOracleReceiptVaultConfig
} from "../../../../../contracts/concrete/vault/ERC20PriceOracleReceiptVault.sol";
import {ERC20PriceOracleReceiptVaultTest, Vm} from "test/foundry/abstract/ERC20PriceOracleReceiptVaultTest.sol";
import {TwoPriceOracle} from "../../../../../contracts/oracle/price/TwoPriceOracle.sol";

contract ERC20PriceOracleReceiptVaultConstructionTest is ERC20PriceOracleReceiptVaultTest {
/// Test ERC20PriceOracleReceiptVault is constracted
function testCheckConstructionEvent(
uint256 fuzzedKeyAlice,
string memory assetName,
string memory assetSymbol,
uint256 timestamp,
uint8 xauDecimals,
uint8 usdDecimals,
uint80 answeredInRound
) external {
// Ensure the fuzzed key is within the valid range for secp256
address alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1);
// Use common decimal bounds for price feeds
// Use 0-20 so we at least have some coverage higher than 18
usdDecimals = uint8(bound(usdDecimals, 0, 20));
xauDecimals = uint8(bound(xauDecimals, 0, 20));
timestamp = bound(timestamp, 0, type(uint32).max);

vm.warp(timestamp);
TwoPriceOracle twoPriceOracle = createTwoPriceOracle(usdDecimals, usdDecimals, timestamp, answeredInRound);
vm.startPrank(alice);

// Start recording logs
vm.recordLogs();

ERC20PriceOracleReceiptVault vault = createVault(address(twoPriceOracle), assetName, assetSymbol);
// Get the logs
Vm.Log[] memory logs = vm.getRecordedLogs();

// Note: To use vm.expectEmit receipt address is needed to be known.
// Find the OffchainAssetReceiptVaultInitialized event log
address msgSender = address(0);
address priceOracle = address(0);
address assetAddress = address(0);
string memory name = "";
string memory symbol = "";
bool eventFound = false; // Flag to indicate whether the event log was found
for (uint256 i = 0; i < logs.length; i++) {
if (
logs[i].topics[0]
== keccak256(
"ERC20PriceOracleReceiptVaultInitialized(address,(address,(address,(address,string,string))))"
)
) {
// Decode the event data
(address sender, ERC20PriceOracleReceiptVaultConfig memory config) =
abi.decode(logs[i].data, (address, ERC20PriceOracleReceiptVaultConfig));
msgSender = sender;
priceOracle = config.priceOracle;
name = config.receiptVaultConfig.vaultConfig.name;
symbol = config.receiptVaultConfig.vaultConfig.symbol;
assetAddress = address(config.receiptVaultConfig.vaultConfig.asset);
eventFound = true; // Set the flag to true since event log was found
break;
}
}
// Assert that the event log was found
assertTrue(eventFound, "ERC20PriceOracleReceiptVaultInitialized event log not found");

assertEq(msgSender, address(iFactory));
assertEq(priceOracle, address(twoPriceOracle));
assert(address(vault) != address(0));
assertEq(keccak256(bytes(vault.name())), keccak256(bytes(name)));
assertEq(keccak256(bytes(vault.symbol())), keccak256(bytes(symbol)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ import {
Math
} from "rain.math.fixedpoint/lib/LibFixedPointDecimalArithmeticOpenZeppelin.sol";
import {IERC20} from "forge-std/interfaces/IERC20.sol";
import {Receipt as ReceiptContract} from "../../../../../contracts/concrete/receipt/Receipt.sol";

contract ERC20PriceOracleReceiptVaultDepositTest is ERC20PriceOracleReceiptVaultTest {
using LibFixedPointDecimalArithmeticOpenZeppelin for uint256;

event DepositWithReceipt(
address sender, address owner, uint256 assets, uint256 shares, uint256 id, bytes receiptInformation
);

/// Test deposit function
function testDeposit(
uint256 fuzzedKeyAlice,
Expand All @@ -35,7 +40,6 @@ contract ERC20PriceOracleReceiptVaultDepositTest is ERC20PriceOracleReceiptVault
vm.warp(timestamp);
TwoPriceOracle twoPriceOracle = createTwoPriceOracle(usdDecimals, usdDecimals, timestamp, answeredInRound);
vm.startPrank(alice);

ERC20PriceOracleReceiptVault vault;
{
vault = createVault(address(twoPriceOracle), assetName, assetName);
Expand All @@ -57,6 +61,9 @@ contract ERC20PriceOracleReceiptVaultDepositTest is ERC20PriceOracleReceiptVault
}
uint256 oraclePrice = twoPriceOracle.price();
uint256 expectedShares = assets.fixedPointMul(oraclePrice, Math.Rounding.Down);
vm.expectEmit(false, false, false, true);
emit DepositWithReceipt(alice, alice, assets, expectedShares, oraclePrice, bytes(""));

vault.deposit(assets, alice, oraclePrice, bytes(""));

// Assert that the total supply is equal to expectedShares
Expand All @@ -78,6 +85,7 @@ contract ERC20PriceOracleReceiptVaultDepositTest is ERC20PriceOracleReceiptVault
// Ensure the fuzzed key is within the valid range for secp256
address alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1);
address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1);
vm.assume(alice != bob);

// Use common decimal bounds for price feeds
// Use 0-20 so we at least have some coverage higher than 18
Expand All @@ -88,6 +96,8 @@ contract ERC20PriceOracleReceiptVaultDepositTest is ERC20PriceOracleReceiptVault
vm.warp(timestamp);
TwoPriceOracle twoPriceOracle = createTwoPriceOracle(usdDecimals, usdDecimals, timestamp, answeredInRound);
vm.startPrank(alice);

vm.recordLogs();
ERC20PriceOracleReceiptVault vault;
{
vault = createVault(address(twoPriceOracle), assetName, assetName);
Expand All @@ -99,22 +109,34 @@ contract ERC20PriceOracleReceiptVaultDepositTest is ERC20PriceOracleReceiptVault

uint256 totalSupply = iAsset.totalSupply();
// Getting ZeroSharesAmount if bounded from 1
assets = bound(assets, 2, totalSupply);
assets = bound(assets, 20, totalSupply);

vm.mockCall(
address(iAsset),
abi.encodeWithSelector(IERC20.transferFrom.selector, alice, vault, assets),
abi.encode(true)
);
}
ReceiptContract receipt = getReceipt();

uint256 oraclePrice = twoPriceOracle.price();
uint256 expectedShares = assets.fixedPointMul(oraclePrice, Math.Rounding.Down);

uint256 aliceReceiptBalance = receipt.balanceOf(alice, oraclePrice);
vm.expectEmit(false, false, false, true);
emit DepositWithReceipt(alice, bob, assets, expectedShares, oraclePrice, bytes(""));

vault.deposit(assets, bob, oraclePrice, bytes(""));
// Assert that the total supply is equal to expectedShares
assertEqUint(vault.totalSupply(), expectedShares);
// Check balance
assertEqUint(vault.balanceOf(bob), expectedShares);

// Check bob's receipt balance
assertEqUint(receipt.balanceOf(bob, oraclePrice), expectedShares);

// Check alice's receipt balance does not change
assertEqUint(receipt.balanceOf(alice, oraclePrice), aliceReceiptBalance);
}

/// Test deposit function with zero assets
Expand Down
Loading

0 comments on commit 75b48e4

Please sign in to comment.