Skip to content

Commit

Permalink
chore: merge
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenvaleri committed Feb 11, 2025
2 parents 9be9685 + c7dfd2a commit 2c0f4f9
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 1 deletion.
20 changes: 20 additions & 0 deletions safe-batches/enable-swap-owner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": "1.0",
"chainId": "1",
"createdAt": 1738828295179,
"meta": {
"name": "Transactions Batch",
"description": "enable-swap-owner",
"txBuilderVersion": "1.10.0",
"createdFromSafeAddress": "0x9D89745fD63Af482ce93a9AdB8B0BbDbb98D3e06",
"createdFromOwnerAddress": "",
"checksum": "0x102a3dcd91b01f97351f36f92ab491ab09e4b218f3525dc41c30cd1e89eb820c"
},
"transactions": [
{
"to": "0x9000fef2846a5253fd2c6ed5241de0fddb404302",
"value": "0x0",
"data": "0x5534fa0c0000000000000000000000000000000000000000000000000000000000000000e318b52b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
}
]
}
20 changes: 20 additions & 0 deletions safe-batches/pendle-usde-yts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": "1.0",
"chainId": "1",
"createdAt": 1738169504927,
"meta": {
"name": "Transactions Batch",
"description": "pendle-usde-yts",
"txBuilderVersion": "1.10.0",
"createdFromSafeAddress": "0x9D89745fD63Af482ce93a9AdB8B0BbDbb98D3e06",
"createdFromOwnerAddress": "",
"checksum": "0x889c99d1f63864e3b2c57f8d94f8ae39cb2a124830051cd4af1b81dca39f757b"
},
"transactions": [
{
"to": "0x9000fef2846a5253fd2c6ed5241de0fddb404302",
"value": "0x0",
"data": "0x5534fa0c0000000000000000000000004a8036efa1307f1ca82d932c0895faa18db0c9eea9059cbb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
}
]
}
46 changes: 45 additions & 1 deletion script/RumpelConfig.sol
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ library RumpelConfig {
address public constant MAINNET_YT_SUSDE_29MAY2025 = 0x1de6Ff19FDA7496DdC12f2161f6ad6427c52aBBe;
address public constant MAINNET_YT_WSTUSR_26MAR2025 = 0xe0e034AfF49755e80b15594ce3A16d74d1a09b2F;

address public constant MAINNET_PENDLE_YT_USDE_27MAR2025 = 0x4A8036EFA1307F1cA82d932C0895faa18dB0c9eE;

address public constant MAINNET_AMPHRETH = 0x5fD13359Ba15A84B76f7F87568309040176167cd;
address public constant MAINNET_SYMBIOTIC_LBTC = 0x9C0823D3A1172F9DdF672d438dec79c39a64f448;

Expand Down Expand Up @@ -259,6 +261,10 @@ library RumpelConfig {
return getRemoveLRT2ProtocolGuardConfigs();
} else if (tagHash == keccak256(bytes("perm-allow-march-may-2025-susde-yts"))) {
return new ProtocolGuardConfig[](0);
} else if (tagHash == keccak256(bytes("pendle-usde-yts"))) {
return new ProtocolGuardConfig[](0);
} else if (tagHash == keccak256(bytes("enable-swap-owner"))) {
return getEnableSwapOwnerProtocolGuard();
} else if (tagHash == keccak256(bytes("initial-resolv-strategies"))) {
return getInitialResolvStrategyProtocolGuardConfigs();
}
Expand Down Expand Up @@ -313,6 +319,10 @@ library RumpelConfig {
return getRemoveLRT2AssetTokenGuardConfigs();
} else if (tagHash == keccak256(bytes("perm-allow-march-may-2025-susde-yts"))) {
return getPermAllowMarchAndMay2025SusdeYTsTokenGuardConfigs();
} else if (tagHash == keccak256(bytes("pendle-usde-yts"))) {
return getPendleUSDEYTsTokenGuardConfigs();
} else if (tagHash == keccak256(bytes("enable-swap-owner"))) {
return new TokenGuardConfig[](0);
} else if (tagHash == keccak256(bytes("initial-resolv-strategies"))) {
return getInitialResolvStrategyTokenGuardConfigs();
}
Expand Down Expand Up @@ -364,6 +374,10 @@ library RumpelConfig {
return new TokenModuleConfig[](0);
} else if (tagHash == keccak256(bytes("perm-allow-march-may-2025-susde-yts"))) {
return getMarchAndMay20252025SusdeYTsTokenModuleConfigs();
} else if (tagHash == keccak256(bytes("pendle-usde-yts"))) {
return new TokenModuleConfig[](0);
} else if (tagHash == keccak256(bytes("enable-swap-owner"))) {
return new TokenModuleConfig[](0);
} else if (tagHash == keccak256(bytes("initial-resolv-strategies"))) {
return new TokenModuleConfig[](0);
}
Expand Down Expand Up @@ -412,6 +426,10 @@ library RumpelConfig {
return new ProtocolModuleConfig[](0);
} else if (tagHash == keccak256(bytes("perm-allow-march-may-2025-susde-yts"))) {
return new ProtocolModuleConfig[](0);
} else if (tagHash == keccak256(bytes("pendle-usde-yts"))) {
return new ProtocolModuleConfig[](0);
} else if (tagHash == keccak256(bytes("enable-swap-owner"))) {
return new ProtocolModuleConfig[](0);
} else if (tagHash == keccak256(bytes("initial-resolv-strategies"))) {
return new ProtocolModuleConfig[](0);
}
Expand Down Expand Up @@ -1117,6 +1135,18 @@ library RumpelConfig {
return configs;
}

function getPendleUSDEYTsTokenGuardConfigs() internal pure returns (TokenGuardConfig[] memory) {
TokenGuardConfig[] memory configs = new TokenGuardConfig[](1);

configs[0] = TokenGuardConfig({
token: MAINNET_PENDLE_YT_USDE_27MAR2025,
transferAllowState: RumpelGuard.AllowListState.ON,
approveAllowState: RumpelGuard.AllowListState.OFF
});

return configs;
}

function getClaimLRT2ProtocolGuardConfigs() internal pure returns (ProtocolGuardConfig[] memory) {
ProtocolGuardConfig[] memory configs = new ProtocolGuardConfig[](1);

Expand Down Expand Up @@ -1242,6 +1272,16 @@ library RumpelConfig {
return configs;
}

function getEnableSwapOwnerProtocolGuard() internal pure returns (ProtocolGuardConfig[] memory) {
ProtocolGuardConfig[] memory configs = new ProtocolGuardConfig[](1);

configs[0] = ProtocolGuardConfig({target: address(0), selectorStates: new SelectorState[](1)});
configs[0].selectorStates[0] =
SelectorState({selector: Safe.swapOwner.selector, state: RumpelGuard.AllowListState.ON});

return configs;
}

function getInitialResolvStrategyProtocolGuardConfigs() internal pure returns (ProtocolGuardConfig[] memory) {
ProtocolGuardConfig[] memory configs = new ProtocolGuardConfig[](2);

Expand Down Expand Up @@ -1295,7 +1335,7 @@ library RumpelConfig {
transferAllowState: RumpelGuard.AllowListState.ON,
approveAllowState: RumpelGuard.AllowListState.ON
});

return configs;
}
}
Expand Down Expand Up @@ -1461,3 +1501,7 @@ interface IEthereumVaultConnector {
interface Permit2 {
function approve(address token, address spender, uint160 amount, uint48 expiration) external;
}

interface Safe {
function swapOwner(address prevOwner, address oldOwner, address newOwner) external;
}
4 changes: 4 additions & 0 deletions src/interfaces/external/ISafe.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ interface ISafe {

function addOwnerWithThreshold(address owner, uint256 _threshold) external;

function removeOwner(address prevOwner, address owner, uint256 _threshold) external;

function swapOwner(address prevOwner, address oldOwner, address newOwner) external;

// Fallback handler functions

function isValidSignature(bytes32 _dataHash, bytes calldata _signature) external view returns (bytes4);
Expand Down
85 changes: 85 additions & 0 deletions test/RumpelWalletSwapOwner.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity =0.8.24;

import {Test} from "forge-std/Test.sol";

import {RumpelGuard} from "../src/RumpelGuard.sol";
import {RumpelModule} from "../src/RumpelModule.sol";
import {InitializationScript} from "../src/InitializationScript.sol";
import {RumpelWalletFactory} from "../src/RumpelWalletFactory.sol";

import {ISafe, Enum} from "../src/interfaces/external/ISafe.sol";
import {RumpelWalletFactoryScripts} from "../script/RumpelWalletFactory.s.sol";

contract RumpelWalletSwapOwnerTest is Test {
RumpelModule public rumpelModule = RumpelModule(0x28c3498B4956f4aD8d4549ACA8F66260975D361a);
RumpelGuard public rumpelGuard = RumpelGuard(0x9000FeF2846A5253fD2C6ed5241De0fddb404302);
RumpelWalletFactory public rumpelWalletFactory = RumpelWalletFactory(0x5774AbCF415f34592514698EB075051E97Db2937);

address alice;
uint256 alicePk;

struct SafeTX {
address to;
uint256 value;
bytes data;
Enum.Operation operation;
}

function setUp() public {
(alice, alicePk) = makeAddrAndKey("alice");

string memory MAINNET_RPC_URL = vm.envString("MAINNET_RPC_URL");
uint256 FORK_BLOCK_NUMBER = 21748243; // Feb-01-2025 12:59:47 AM +UTC
vm.createSelectFork(MAINNET_RPC_URL, FORK_BLOCK_NUMBER);
}

function test_SwapOwner() public {
RumpelWalletFactoryScripts scripts = new RumpelWalletFactoryScripts();

address[] memory owners = new address[](1);
owners[0] = address(alice);

InitializationScript.InitCall[] memory initCalls = new InitializationScript.InitCall[](0);
address safe = rumpelWalletFactory.createWallet(owners, 1, initCalls);

address NEW_OWNER = address(0x123);

assertEq(ISafe(safe).getOwners().length, 1);
assertEq(ISafe(safe).getOwners()[0], address(alice));

bytes memory swapOwnerData =
abi.encodeWithSelector(ISafe.swapOwner.selector, address(0x1), address(alice), NEW_OWNER);
vm.expectRevert(
abi.encodeWithSelector(RumpelGuard.CallNotAllowed.selector, address(safe), bytes4(swapOwnerData))
);
this._execSafeTx(ISafe(safe), safe, 0, swapOwnerData, Enum.Operation.Call);

assertEq(ISafe(safe).getOwners().length, 1);
assertEq(ISafe(safe).getOwners()[0], address(alice));

// Run the script to enable the swapOwner call
scripts.updateGuardAndModuleLists(rumpelGuard, rumpelModule, "enable-swap-owner");

this._execSafeTx(ISafe(safe), safe, 0, swapOwnerData, Enum.Operation.Call);

assertEq(ISafe(safe).getOwners().length, 1);
assertEq(ISafe(safe).getOwners()[0], NEW_OWNER);
}

function _execSafeTx(ISafe safe, address to, uint256 value, bytes memory data, Enum.Operation operation) public {
SafeTX memory safeTX = SafeTX({to: to, value: value, data: data, operation: operation});

uint256 nonce = safe.nonce();

bytes32 txHash = safe.getTransactionHash(
safeTX.to, safeTX.value, safeTX.data, safeTX.operation, 0, 0, 0, address(0), payable(address(0)), nonce
);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(alicePk, txHash);
bytes memory signature = abi.encodePacked(r, s, v);

safe.execTransaction(
safeTX.to, safeTX.value, safeTX.data, safeTX.operation, 0, 0, 0, address(0), payable(address(0)), signature
);
}
}

0 comments on commit 2c0f4f9

Please sign in to comment.