Skip to content

Commit

Permalink
issue 3 griefing with min bid increment 0
Browse files Browse the repository at this point in the history
  • Loading branch information
St4rgarden committed May 1, 2024
1 parent 34ae9b4 commit 5b604de
Show file tree
Hide file tree
Showing 2 changed files with 289 additions and 0 deletions.
8 changes: 8 additions & 0 deletions contracts/auction/EnglishPeriodicAuctionInternal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ abstract contract EnglishPeriodicAuctionInternal is
EnglishPeriodicAuctionStorage.Layout
storage l = EnglishPeriodicAuctionStorage.layout();

require(
minBidIncrement > 0,
'EnglishPeriodicAuction: Min bid increment must be greater than 0'
);
l.isInitialized = true;
l.initialBidder = initialBidder;
l.initialPeriodStartTimeOffset = initialPeriodStartTimeOffset;
Expand All @@ -53,6 +57,10 @@ abstract contract EnglishPeriodicAuctionInternal is
uint256 bidExtensionSeconds,
uint256 startingBid
) internal {
require(
minBidIncrement > 0,
'EnglishPeriodicAuction: Min bid increment must be greater than 0'
);
_setRepossessor(repossessor);
_setAuctionLengthSeconds(auctionLengthSeconds);
_setMinBidIncrement(minBidIncrement);
Expand Down
281 changes: 281 additions & 0 deletions test/auction/EnglishPeriodicAuction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,251 @@ describe('EnglishPeriodicAuction', function () {
return instance;
}

async function getRevertInstance({
hasOwner = false,
auctionLengthSeconds = 100,
licensePeriod = 1,
initialPeriodStartTime = 2,
initialPeriodStartTimeOffset = 0,
startingBid = ethers.utils.parseEther('1'),
bidExtensionWindowLengthSeconds = 10,
bidExtensionSeconds = 20,
shouldMint = false,
repossessor = nonOwner.address,
initialBidder = owner.address,
} = {}) {
const pcoParamsFacetFactory = await ethers.getContractFactory(
'PeriodicPCOParamsFacet',
);
const pcoParamsFacetInstance = await pcoParamsFacetFactory.deploy();
await pcoParamsFacetInstance.deployed();

const licenseMockFactory = await ethers.getContractFactory(
'NativeStewardLicenseMock',
);
const licenseMock = await licenseMockFactory.deploy();
await licenseMock.deployed();

const beneficiaryFactory = await ethers.getContractFactory(
'BeneficiaryMock',
);
const beneficiaryMock = await beneficiaryFactory.deploy();
await beneficiaryMock.deployed();

const allowlistFactory = await ethers.getContractFactory('AllowlistMock');
const allowlistMock = await allowlistFactory.deploy();
await allowlistMock.deployed();

const accessControlFactory = await ethers.getContractFactory(
'AccessControlFacet',
);
const accessControl = await accessControlFactory.deploy();
await accessControl.deployed();

const facetFactory = await ethers.getContractFactory(
'EnglishPeriodicAuctionFacet',
);
const facetInstance = await facetFactory.deploy();
await facetInstance.deployed();

const factory = await ethers.getContractFactory('SingleCutDiamond');
instance = await factory.deploy([
{
target: pcoParamsFacetInstance.address,
initTarget: pcoParamsFacetInstance.address,
initData: pcoParamsFacetInstance.interface.encodeFunctionData(
'initializePCOParams(address,uint256,uint256,uint256)',
[await owner.getAddress(), licensePeriod, 1, 10],
),
selectors: [
pcoParamsFacetInstance.interface.getSighash(
'initializePCOParams(address,uint256,uint256,uint256)',
),
pcoParamsFacetInstance.interface.getSighash('licensePeriod()'),
pcoParamsFacetInstance.interface.getSighash(
'setLicensePeriod(uint256)',
),
pcoParamsFacetInstance.interface.getSighash('feeNumerator()'),
pcoParamsFacetInstance.interface.getSighash('feeDenominator()'),
],
},
{
target: licenseMock.address,
initTarget: licenseMock.address,
initData: licenseMock.interface.encodeFunctionData(
'initializeStewardLicense(address,address,address,uint256,bool,string,string,string)',
[
await owner.getAddress(),
await owner.getAddress(),
await owner.getAddress(),
10,
shouldMint,
'name',
'symbol',
'tokenURI',
],
),
selectors: [
licenseMock.interface.getSighash(
'initializeStewardLicense(address,address,address,uint256,bool,string,string,string)',
),
licenseMock.interface.getSighash(
'triggerTransfer(address,address,uint256)',
),
licenseMock.interface.getSighash('ownerOf(uint256)'),
licenseMock.interface.getSighash('mint(address,uint256)'),
licenseMock.interface.getSighash('exists(uint256)'),
licenseMock.interface.getSighash(
'transferFrom(address,address,uint256)',
),
licenseMock.interface.getSighash('maxTokenCount()'),
licenseMock.interface.getSighash('mintToken(address,uint256)'),
licenseMock.interface.getSighash(
'addTokenToCollection(address,string,uint256)',
),
],
},
{
target: beneficiaryMock.address,
initTarget: beneficiaryMock.address,
initData: beneficiaryMock.interface.encodeFunctionData(
'initializeMockBeneficiary(address)',
[await nonOwner.getAddress()],
),
selectors: [
beneficiaryMock.interface.getSighash(
'initializeMockBeneficiary(address)',
),
beneficiaryMock.interface.getSighash('distribute()'),
],
},
{
target: allowlistMock.address,
initTarget: allowlistMock.address,
initData: allowlistMock.interface.encodeFunctionData(
'setIsAllowed(bool)',
[true],
),
selectors: [
allowlistMock.interface.getSighash('isAllowed(address)'),
allowlistMock.interface.getSighash('setIsAllowed(bool)'),
],
},
{
target: facetInstance.address,
initTarget: facetInstance.address,
initData: hasOwner
? facetInstance.interface.encodeFunctionData(
'initializeAuction(address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)',
[
await owner.getAddress(),
repossessor,
initialBidder,
initialPeriodStartTime,
initialPeriodStartTimeOffset,
startingBid,
auctionLengthSeconds,
0,
bidExtensionWindowLengthSeconds,
bidExtensionSeconds,
],
)
: facetInstance.interface.encodeFunctionData(
'initializeAuction(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)',
[
repossessor,
initialBidder,
initialPeriodStartTime,
initialPeriodStartTimeOffset,
startingBid,
auctionLengthSeconds,
0,
bidExtensionWindowLengthSeconds,
bidExtensionSeconds,
],
),
selectors: [
hasOwner
? facetFactory.interface.getSighash(
'initializeAuction(address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)',
)
: facetFactory.interface.getSighash(
'initializeAuction(address,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)',
),
facetFactory.interface.getSighash('isAuctionPeriod(uint256)'),
facetFactory.interface.getSighash('isReadyForTransfer(uint256)'),
facetFactory.interface.getSighash('placeBid(uint256,uint256)'),
facetFactory.interface.getSighash('closeAuction(uint256)'),
facetFactory.interface.getSighash('calculateFeeFromBid(uint256)'),
facetFactory.interface.getSighash('repossessor()'),
facetFactory.interface.getSighash('setRepossessor(address)'),
facetFactory.interface.getSighash('initialPeriodStartTime()'),
facetFactory.interface.getSighash('initialBidder()'),
facetFactory.interface.getSighash('setAuctionLengthSeconds(uint256)'),
facetFactory.interface.getSighash('auctionLengthSeconds()'),
facetFactory.interface.getSighash('minBidIncrement()'),
facetFactory.interface.getSighash('setMinBidIncrement(uint256)'),
facetFactory.interface.getSighash(
'setBidExtensionWindowLengthSeconds(uint256)',
),
facetFactory.interface.getSighash(
'bidExtensionWindowLengthSeconds()',
),
facetFactory.interface.getSighash('bidExtensionSeconds()'),
facetFactory.interface.getSighash('setBidExtensionSeconds(uint256)'),
facetFactory.interface.getSighash('bidOf(uint256,address)'),
facetFactory.interface.getSighash('bidOf(uint256,uint256,address)'),
facetFactory.interface.getSighash('highestBid(uint256)'),
facetFactory.interface.getSighash('highestBid(uint256,uint256)'),
facetFactory.interface.getSighash('currentAuctionRound(uint256)'),
facetFactory.interface.getSighash('auctionStartTime(uint256)'),
facetFactory.interface.getSighash('auctionEndTime(uint256)'),
facetFactory.interface.getSighash('cancelBid(uint256,uint256)'),
facetFactory.interface.getSighash(
'cancelAllBidsAndWithdrawCollateral(uint256)',
),
facetFactory.interface.getSighash(
'cancelBidAndWithdrawCollateral(uint256,uint256)',
),
facetFactory.interface.getSighash('withdrawCollateral()'),
facetFactory.interface.getSighash(
'setAuctionParameters(address,uint256,uint256,uint256,uint256,uint256)',
),
facetFactory.interface.getSighash('startingBid()'),
facetFactory.interface.getSighash('setStartingBid(uint256)'),
facetFactory.interface.getSighash('availableCollateral(address)'),
facetFactory.interface.getSighash(
'lockedCollateral(uint256,address)',
),
],
},
{
target: accessControl.address,
initTarget: accessControl.address,
initData: accessControl.interface.encodeFunctionData(
'initializeAccessControl(address)',
[admin.address],
),
selectors: [
accessControl.interface.getSighash(
'initializeAccessControl(address)',
),
accessControl.interface.getSighash('grantRole(bytes32,address)'),
accessControl.interface.getSighash('renounceRole(bytes32)'),
accessControl.interface.getSighash('hasRole(bytes32,address)'),
],
},
]);
await instance.deployed();

instance = await ethers.getContractAt(
'EnglishPeriodicAuctionFacet',
instance.address,
);

return instance;
}

async function getSpecialInstance({
hasOwner = false,
auctionLengthSeconds = 100,
Expand Down Expand Up @@ -1009,6 +1254,36 @@ describe('EnglishPeriodicAuction', function () {
);
});

it('should revert if bid is equal to highest', async function () {
// Auction start: Now - 200
// Auction end: Now + 100
const instance = await getInstance({
auctionLengthSeconds: 300,
initialPeriodStartTime: (await time.latest()) - 200,
licensePeriod: 1000,
});

const bidAmount1 = ethers.utils.parseEther('1.1');
const feeAmount1 = await instance.calculateFeeFromBid(bidAmount1);
const collateralAmount1 = feeAmount1.add(bidAmount1);

const bidAmount2 = ethers.utils.parseEther('1.1');
const feeAmount2 = await instance.calculateFeeFromBid(bidAmount2);
const collateralAmount2 = feeAmount2.add(bidAmount2);

await instance
.connect(bidder1)
.placeBid(0, bidAmount1, { value: collateralAmount1 });

await expect(
instance.connect(bidder2).placeBid(0, bidAmount2, {
value: collateralAmount2,
}),
).to.be.revertedWith(
'EnglishPeriodicAuction: Bid amount must be greater than highest outstanding bid',
);
});

it('should revert if bid amount is not correct', async function () {
// Auction start: Now - 200
// Auction end: Now + 100
Expand Down Expand Up @@ -2986,6 +3261,12 @@ describe('EnglishPeriodicAuction', function () {
'StewardLicenseFacet: New period time must be greater than or equal to current period time',
);
});

it('should revert if min bid increment is zero', async function () {
await expect(getRevertInstance()).to.be.revertedWith(
'EnglishPeriodicAuction: Min bid increment must be greater than 0',
);
});
});
});
});

0 comments on commit 5b604de

Please sign in to comment.