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

FrxTransparentProxy with arbitrary reader #25

Open
wants to merge 3 commits into
base: master
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
2 changes: 2 additions & 0 deletions src/FraxTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Strings } from "./StringsHelper.sol";
abstract contract FraxTest is VmHelper, Test {
/// @notice Differential State Storage
uint256[] internal snapShotIds;
uint256 currentSnapShotId;
function()[] internal setupFunctions;

/// @notice EIP-1967 Slots
Expand All @@ -22,6 +23,7 @@ abstract contract FraxTest is VmHelper, Test {
if (snapShotIds.length == 0) _;
for (uint256 i = 0; i < snapShotIds.length; i++) {
uint256 _originalSnapshotId = vm.snapshot();
// currentSnapShotId = snapShotIds[i];
if (!vm.revertTo(snapShotIds[i])) {
revert VmDidNotRevert(snapShotIds[i]);
}
Expand Down
43 changes: 43 additions & 0 deletions src/FrxTransparentProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: ISC
pragma solidity >=0.8.0;

import { TransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";

// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ====================== FrxTransparentProxy =========================
// ====================================================================

contract FrxTransparentProxy is TransparentUpgradeableProxy {
constructor(
address _logic,
address _initialAdmin,
bytes memory _data
) TransparentUpgradeableProxy(_logic, _initialAdmin, _data) {}

// ================================================================
// ~~~~~~~~~~~~~~~~~~~~~~~~~~ Extension ~~~~~~~~~~~~~~~~~~~~~~~~~~
// ================================================================

/// @notice Low level function to read arbitrary slots from the proxy
/// @param slot The slot to read
/// @return data The bytes32 data that is stored on that slot
/// @dev Ensure that `0x53e1edcb` does not result in selector clash on
/// The implementation contract
function readArbitrary(bytes32 slot) public view returns (bytes32 data) {
assembly {
data := sload(slot)
}
}

/// @notice Silence compiler warnings
receive() external payable {
_fallback();
}
}
50 changes: 50 additions & 0 deletions test/TestFrxProxy.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-License-Identifier: ISC
pragma solidity >=0.8.0;

import "../src/FraxTest.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { FrxTransparentProxy } from "src/FrxTransparentProxy.sol";

contract TestFrxTransparentProxy is FraxTest {
address instance;
FrxTransparentProxy frxUsdProxy;
IERC20 frxUsd;

function setUp() public {
vm.createSelectFork("https://rpc.frax.com", 16_557_873);
vm.etch(
address(0xC2A4), /// The Unicode character '¤' encoded in UTF-8 and represented as hex
hex"11"
);
instance = address(new FrxTransparentProxy(address(0xC2A4), address(0xC2A4), hex""));
vm.etch(0xFc00000000000000000000000000000000000001, instance.code);
frxUsdProxy = FrxTransparentProxy(payable(0xFc00000000000000000000000000000000000001));
frxUsd = IERC20(0xFc00000000000000000000000000000000000001);
}

function testReadImplementationSlot() public {
bytes32 impl = frxUsdProxy.readArbitrary(IMPLEMENTATION_SLOT);
assertEq({
a: address(uint160(uint256(impl))),
b: 0x00000aFb5e62fd81bC698E418dBfFE5094cB38E0,
err: "// THEN: Implementation not as expected"
});
}

function testReadAdminSlot() public {
bytes32 admin = frxUsdProxy.readArbitrary(ADMIN_SLOT);
console.logBytes32(admin);
assertEq({
a: address(uint160(uint256(admin))),
b: 0xfC0000000000000000000000000000000000000a,
err: "// THEN: Admin not as expected"
});
}

function testReadBalanceData() public {
/// Derive the balance slot
bytes32 balanceSlot = keccak256(abi.encode(0x31562ae726AFEBe25417df01bEdC72EF489F45b3, 0));
bytes32 balance = frxUsdProxy.readArbitrary(balanceSlot);
assertEq({ a: uint256(balance), b: 879.253786510845295473e18, err: "// THEN: balance not as expected" });
}
}
17 changes: 14 additions & 3 deletions test/TestMultipleSetup.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ pragma solidity >=0.8.0;
import "../src/FraxTest.sol";

contract TestMultipleSetup is FraxTest {
uint256 value;
uint256 public value;
uint256 public runsPassed;

function initializeValueOne() public {
value = 25;
Expand All @@ -23,9 +24,19 @@ contract TestMultipleSetup is FraxTest {
setupFunctions.push(initializeValueTwo);
setupFunctions.push(initializeValueThree);
addSetupFunctions(setupFunctions);
vm.makePersistent(address(this));
}

function testFailAssertValue() public useMultipleSetupFunctions {
assertEq(value, 5);
function revertIfNotFive(uint256 value) public {
if (value != 5) revert();
else revert("Run Passed");
}

/// @notice Should fail if value is not 5, should fail differently if
/// value == 5
function testAssertValue() public useMultipleSetupFunctions {
if (value != 5) vm.expectRevert();
else vm.expectRevert(bytes("Run Passed"));
this.revertIfNotFive(value);
}
}
Loading