File: src/vaults/PxGmxReward.sol
41: if (_pxGmx == address(0)) revert ZeroAddress();
Impact
Priex encompasses many smart contracts. Consequently, there are many address/contract assignments. However, addresses and contracts are assigned to state variables under very loose verification, i.e. a non-zero address will pass the validation. This may lead to serious implications or even chaos if an inappropriate contract address is assigned in use since there is no way to predict the consequences. So, it is necessary to take every measure to prevent wrong contracts in use.
Tools Used
Manual audit.
Recommended Mitigation Steps
ERC165 is a standard to detect and publish what interfaces a smart contract implements. This can be used to verify whether a contract address supports specific interfaces, which can dramatically reduce the risk of using a wrong contract. Openzeppelin has implemented the standard and we can use it for our purpose.
The below is an example of how to use ERC165 tools from Openzeppelin to implement contract interface verification. Contracts of Priex should implement this mechanism where possible so as to reduce the risk of using wrong contracts.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import {ERC165Storage} from "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol";
interface IArbitraryTokenStorage {
function withdrawToOwner(IERC20 token) external;
}
contract NewPxToken is ERC165Storage, IArbitraryTokenStorage, ERC20 {
address public owner;
error NoEnoughBalance();
error TransferFailed();
constructor() ERC20("New Px Token", "NPT") {
owner = msg.sender;
// to register function interfaces in constructor or initialize function
_registerInterface(type(IArbitraryTokenStorage).interfaceId);
_registerInterface(type(IERC20).interfaceId);
}
function withdrawToOwner(IERC20 token) external {
uint256 balance = token.balanceOf(address(this));
if(balance == 0) revert NoEnoughBalance();
if(!token.transfer(owner, balance)) revert TransferFailed();
}
}
contract SetNewPxToken {
using ERC165Checker for address;
NewPxToken public newPxToken;
error NotSupportArbitraryTokenStorage();
error NotSupportERC20();
function setContractInstance(address _addr) public {
// verify whether the input address `_addr` supports required interfaces
if(!_addr.supportsInterface(type(IArbitraryTokenStorage).interfaceId)) revert NotSupportArbitraryTokenStorage();
if(!_addr.supportsInterface(type(IERC20).interfaceId)) revert NotSupportERC20();
newPxToken = NewPxToken(_addr);
}
}
Lines of code
https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/PirexGmx.sol#L182-L191 https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/PirexRewards.sol#L94 https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/PxERC20.sol#L30 https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/vaults/AutoPxGlp.sol#L75 https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/vaults/AutoPxGmx.sol#L82 https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/vaults/PxGmxReward.sol#L41
Vulnerability details
Instances: (44):
Link to code
Link to code
Link to code
Link to code
Link to code
Link to code
Impact
Priex encompasses many smart contracts. Consequently, there are many address/contract assignments. However, addresses and contracts are assigned to state variables under very loose verification, i.e. a non-zero address will pass the validation. This may lead to serious implications or even chaos if an inappropriate contract address is assigned in use since there is no way to predict the consequences. So, it is necessary to take every measure to prevent wrong contracts in use.
Tools Used
Manual audit.
Recommended Mitigation Steps
ERC165 is a standard to detect and publish what interfaces a smart contract implements. This can be used to verify whether a contract address supports specific interfaces, which can dramatically reduce the risk of using a wrong contract. Openzeppelin has implemented the standard and we can use it for our purpose. The below is an example of how to use ERC165 tools from Openzeppelin to implement contract interface verification. Contracts of Priex should implement this mechanism where possible so as to reduce the risk of using wrong contracts.