-
Notifications
You must be signed in to change notification settings - Fork 311
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: add NoDelegateCall modifiers to DualVMToken
- Loading branch information
Showing
8 changed files
with
337 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.27; | ||
|
||
contract DualVmTokenHack { | ||
address target; | ||
uint256 constant AMOUNT = 1337; | ||
|
||
constructor(address _target) { | ||
target = _target; | ||
} | ||
|
||
function tryApproveEvm() external returns (bool success) { | ||
(success,) = target.delegatecall( | ||
abi.encodeWithSelector(bytes4(keccak256("approve(address,uint256)")), address(this), AMOUNT) | ||
); | ||
} | ||
|
||
function tryApproveStarknet() external returns (bool success) { | ||
(success,) = target.delegatecall( | ||
abi.encodeWithSelector( | ||
bytes4(keccak256("approve(uint256,uint256)")), uint256(uint160(address(this))), AMOUNT | ||
) | ||
); | ||
} | ||
|
||
function tryTransferEvm() external returns (bool success) { | ||
(success,) = target.delegatecall( | ||
abi.encodeWithSelector(bytes4(keccak256("transfer(address,uint256)")), address(this), AMOUNT) | ||
); | ||
} | ||
|
||
function tryTransferStarknet() external returns (bool success) { | ||
(success,) = target.delegatecall( | ||
abi.encodeWithSelector( | ||
bytes4(keccak256("transfer(uint256,uint256)")), uint256(uint160(address(this))), AMOUNT | ||
) | ||
); | ||
} | ||
|
||
function tryTransferFromEvmEvm() external returns (bool success) { | ||
(success,) = target.delegatecall( | ||
abi.encodeWithSelector( | ||
bytes4(keccak256("transferFrom(address,address,uint256)")), msg.sender, address(this), AMOUNT | ||
) | ||
); | ||
} | ||
|
||
function tryTransferFromStarknetEvm() external returns (bool success) { | ||
(success,) = target.delegatecall( | ||
abi.encodeWithSelector( | ||
bytes4(keccak256("transferFrom(uint256,address,uint256)")), | ||
uint256(uint160(msg.sender)), | ||
address(this), | ||
AMOUNT | ||
) | ||
); | ||
} | ||
|
||
function tryTransferFromEvmStarknet() external returns (bool success) { | ||
(success,) = target.delegatecall( | ||
abi.encodeWithSelector( | ||
bytes4(keccak256("transferFrom(address,uint256,uint256)")), | ||
msg.sender, | ||
uint256(uint160(address(this))), | ||
AMOUNT | ||
) | ||
); | ||
} | ||
|
||
function tryTransferFromStarknetStarknet() external returns (bool success) { | ||
(success,) = target.delegatecall( | ||
abi.encodeWithSelector( | ||
bytes4(keccak256("transferFrom(uint256,uint256,uint256)")), | ||
uint256(uint160(msg.sender)), | ||
uint256(uint160(address(this))), | ||
AMOUNT | ||
) | ||
); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
solidity_contracts/src/Security/L2KakarotMessagingHack.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.27; | ||
|
||
import {L2KakarotMessaging} from "../L1L2Messaging/L2KakarotMessaging.sol"; | ||
|
||
contract L2MessagingHack { | ||
L2KakarotMessaging public immutable target; | ||
|
||
constructor(address _target) { | ||
target = L2KakarotMessaging(_target); | ||
} | ||
|
||
function trySendMessageToL1(address to, bytes calldata data) external returns (bool success) { | ||
// Try to send message through delegatecall | ||
(success,) = | ||
address(target).delegatecall(abi.encodeWithSelector(L2KakarotMessaging.sendMessageToL1.selector, to, data)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
// Author: Uniswap Labs https://github.com/Uniswap/v3-core/blob/main/contracts/NoDelegateCall.sol | ||
pragma solidity 0.8.27; | ||
|
||
/// @title Prevents delegatecall to a contract | ||
/// @notice Base contract that provides a modifier for preventing delegatecall to methods in a child contract | ||
abstract contract NoDelegateCall { | ||
/// @dev The original address of this contract | ||
address private immutable original; | ||
|
||
constructor() { | ||
// Immutables are computed in the init code of the contract, and then inlined into the deployed bytecode. | ||
// In other words, this variable won't change when it's checked at runtime. | ||
original = address(this); | ||
} | ||
|
||
/// @dev Private method is used instead of inlining into modifier because modifiers are copied into each method, | ||
/// and the use of immutable means the address bytes are copied in every place the modifier is used. | ||
function checkNotDelegateCall() private view { | ||
require(address(this) == original); | ||
} | ||
|
||
/// @notice Prevents delegatecall into the modified method | ||
modifier noDelegateCall() { | ||
checkNotDelegateCall(); | ||
_; | ||
} | ||
} |
Oops, something went wrong.