Root + Impact
Description
-
The getOrderDetailsString()
returns a string that shows all the info related to an order.
-
However, due the following lines the function does not consider the symbols for tokens other than the core tokens. hence, for non-core tokens the symbol does not return any value.
string memory tokenSymbol;
if (order.tokenToSell == address(iWETH)) {
tokenSymbol = "wETH";
} else if (order.tokenToSell == address(iWBTC)) {
tokenSymbol = "wBTC";
} else if (order.tokenToSell == address(iWSOL)) {
tokenSymbol = "wSOL";
}
Risk
Likelihood:
*Whenever getOrderDetailsString()
is called for an order which involves a non core token
Impact:
Proof of Concept
Place the following function in TestOrderBook.t.sol
and run with forge test --mt test_wrongTokenSymbol -vv
:
function test_wrongTokenSymbol() public {
MockWETH newMock = new MockWETH(18);
vm.prank(owner);
book.setAllowedSellToken(address(newMock), true);
newMock.mint(alice, 10e18);
vm.startPrank(alice);
newMock.approve(address(book), 10e18);
uint256 aliceId = book.createSellOrder(address(newMock), 8e18, 1e18, 3 days);
string memory res = book.getOrderDetailsString(aliceId);
console2.log(res);
}
In the output we get:
[⠊] Compiling...
[⠒] Compiling 1 files with Solc 0.8.26
[⠑] Solc 0.8.26 finished in 530.20ms
Compiler run successful!
Ran 1 test for test/TestOrderBook.t.sol:TestOrderBook
[PASS] test_wrongTokenSymbol() (gas: 1292211)
Logs:
Order ID: 1
Seller: 0xaf6db259343d020e372f4ab69cad536aaf79d0ac
Selling: 8000000000000000000
Asking Price: 1000000000000000000 USDC
Deadline Timestamp: 259201
Status: Active
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.71ms (680.12µs CPU time)
Ran 1 test suite in 3.62ms (2.71ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)
As we can see, the Selling field does not mention the symbol of the token being sold.
Recommended Mitigation
Use the symbol()
function from ERC20 contract to access the token symbol
function getOrderDetailsString(uint256 _orderId) public view returns (string memory details) {
Order storage order = orders[_orderId];
if (order.seller == address(0)) revert OrderNotFound(); // Check if order exists
- string memory tokenSymbol;
+ string memory tokenSymbol = IERC20(order.tokenToSell).symbol();
- if (order.tokenToSell == address(iWETH)) {
- tokenSymbol = "wETH";
- } else if (order.tokenToSell == address(iWBTC)) {
- tokenSymbol = "wBTC";
- } else if (order.tokenToSell == address(iWSOL)) {
- tokenSymbol = "wSOL";
- }