Sparkn

CodeFox Inc.
DeFiFoundryProxy
15,000 USDC
View results
Submission Details
Severity: low
Valid

Temporary DOS is possible distributing to winners while using tokens with `blacklist`

Summary

The Distributor contract uses a looping mechanism to distribute tokens to winners but tokens like USDT (which protocol plans on using as an reward token) has blacklist addresses. In that case, the distribution process would be difficult for the organizer as the transaction will revert whenever called.

Vulnerability Details

The main concept here is if the address of any winner is blacklisted by token contract then it can not receive funds and reverting the entire transaction. Below is a proof of concept how a blacklisted address can cause a temporary DOS and reverting the whole transaction each time.

const { expect } = require("chai");
const { ethers } = require("hardhat");
const contestId =
"0x7465737400000000000000000000000000000000000000000000000000000000";
const randomBytes =
"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
async function getTime(days) {
const blockNumber = await ethers.provider.getBlockNumber();
const block = await ethers.provider.getBlock(blockNumber);
const currentTimestamp = block.timestamp;
const futureTimestamp = currentTimestamp + days * 86400;
return futureTimestamp;
}
async function deployMockToken(acc) {
const testToken = await ethers.getContractFactory("MockERC20");
const connectToken = testToken.connect(acc);
const MockERC20 = await connectToken.deploy();
return MockERC20;
}
async function getSomeTokens(acc, token, amount) {
await token.connect(acc).mint(amount);
}
async function deployImplementation(_factoryAddress, _stadiumAddress) {
const distributor = await ethers.getContractFactory("Distributor");
const Distributor = await distributor.deploy(
_factoryAddress,
_stadiumAddress
);
return Distributor;
}
describe("CodeHawks", function () {
it("SPARKN", async function () {
const [
ERC20Deployer,
stadiumAddress,
factoryDeployer,
organizer,
winner,
blacklistedWinner,
] = await ethers.getSigners();
const USDT = await deployMockToken(ERC20Deployer);
expect(await USDT.owner()).to.equal(ERC20Deployer.address);
await USDT.connect(ERC20Deployer).addToBlacklist(blacklistedWinner);
expect(await USDT.isBlacklisted(blacklistedWinner)).to.equal(true);
expect(await USDT.isBlacklisted(winner)).to.equal(false);
await getSomeTokens(organizer, USDT, 10000000);
const factory = await ethers.getContractFactory("ProxyFactory");
const connectedFactory = factory.connect(factoryDeployer);
const ProxyFactory = await connectedFactory.deploy([USDT]);
const Distributor = await deployImplementation(
ProxyFactory.target,
stadiumAddress
);
const getData = await ethers.getContractFactory("delegateCall");
const delegateCall = await getData.deploy();
const delegateCallData = await delegateCall.getCallData(
USDT,
[winner, blacklistedWinner],
[5000, 4500],
randomBytes
);
const closeTime = await getTime(10);
await ProxyFactory.connect(factoryDeployer).setContest(
organizer,
contestId,
closeTime,
Distributor.target
);
const saltofContest = await ProxyFactory._calculateSalt(
organizer,
contestId,
Distributor.target
);
const proxy_address = await ProxyFactory.getProxyAddress(
saltofContest,
Distributor.target
);
await USDT.connect(organizer).transfer(proxy_address, 100000);
try {
await ProxyFactory.connect(organizer).deployProxyAndDistribute(
contestId,
Distributor.target,
delegateCallData
);
} catch (error) {
console.log(error);
}
});
});

And the output is:

Error: VM Exception while processing transaction: reverted with custom error 'ProxyFactory__DelegateCallFailed()'

Impact

In conclusion, this issue can not brick the system entirely, and can not permanently stop organizer to distribute rewards to the winners. However, it may still cause a temporary DoS.

Tools Used

  1. Manual Review

  2. Hardhat

Recommendations

  1. Recommended to use an off-chain monitoring service to monitor these types of blacklisted addresses.

  2. Another alternative would be to implement a "pull pattern" rather than a "push pattern"

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!