Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d78ae17
Migrate 'arrays'
RenanSouza2 Nov 12, 2023
52b3bd8
fix findUpperBound and add findLowerBound
Amxx Nov 17, 2023
9a1411b
add memory variants
Amxx Nov 20, 2023
c4726c8
Merge branch 'master' into feature/array-bound-with-duplicates
Amxx Jan 18, 2024
a6ec616
fix merge
Amxx Jan 18, 2024
23e8db9
fix lint
Amxx Jan 18, 2024
c72591f
minimize change
Amxx Jan 18, 2024
9162e42
add changeset
Amxx Jan 18, 2024
ed1de5b
Apply suggestions from code review
Amxx Jan 18, 2024
4c1c7f4
add Arrays.sort
Amxx Jan 18, 2024
abd07b6
add sort test
Amxx Jan 18, 2024
1e89815
fix lint
Amxx Jan 18, 2024
b73989d
codespell
Amxx Jan 19, 2024
79bf367
add fuzzing tests for Arrays.sort
Amxx Jan 19, 2024
f2d49ef
add unsafeMemoryAccess tests
Amxx Jan 22, 2024
c043453
Merge branch 'master' into feature/quicksort
Amxx Jan 29, 2024
c75de32
fix lint
Amxx Jan 29, 2024
f823bee
lint
Amxx Jan 30, 2024
c90f12b
Update contracts/utils/Arrays.sol
Amxx Feb 2, 2024
180a969
Update contracts/utils/Arrays.sol
Amxx Feb 2, 2024
708972f
Apply suggestions from code review
Amxx Feb 2, 2024
533e6cd
Merge branch 'master' into feature/quicksort
Amxx Feb 2, 2024
3f1f0a5
Update contracts/utils/Arrays.sol
ernestognw Feb 2, 2024
5a0ad7f
Add comments to `_quickSort`
ernestognw Feb 3, 2024
a8e6f54
Lint
ernestognw Feb 3, 2024
7600291
Update contracts/utils/Arrays.sol
Amxx Feb 5, 2024
6f163d2
Update contracts/utils/Arrays.sol
Amxx Feb 5, 2024
8983066
cache the pivot and improve doc
Amxx Feb 5, 2024
8704763
Apply suggestions from code review
Amxx Feb 5, 2024
4336e2e
Merge branch 'master' into feature/quicksort
Amxx Feb 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Migrate 'arrays'
  • Loading branch information
RenanSouza2 committed Nov 12, 2023
commit d78ae17d576ea9619202932110484145a5850ae7
7 changes: 7 additions & 0 deletions test/helpers/random.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const { ethers } = require("hardhat");

function randomHex(length) {
return `0x${Buffer.from(ethers.randomBytes(length)).toString('hex')}`
}

module.exports = { randomHex }
80 changes: 50 additions & 30 deletions test/utils/Arrays.test.js
Original file line number Diff line number Diff line change
@@ -1,88 +1,106 @@
require('@openzeppelin/test-helpers');

const { ethers } = require('hardhat');
const { expect } = require('chai');
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
const { randomHex } = require('../helpers/random');

const AddressArraysMock = 'AddressArraysMock';
const Bytes32ArraysMock = 'Bytes32ArraysMock';
const Uint256ArraysMock = 'Uint256ArraysMock';

const AddressArraysMock = artifacts.require('AddressArraysMock');
const Bytes32ArraysMock = artifacts.require('Bytes32ArraysMock');
const Uint256ArraysMock = artifacts.require('Uint256ArraysMock');
async function fixture () {}

contract('Arrays', function () {
describe('Arrays', function () {
describe('findUpperBound', function () {
context('Even number of elements', function () {
describe('Even number of elements', function () {
const EVEN_ELEMENTS_ARRAY = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20];

const fixture = async () => {
const arrays = await ethers.deployContract(Uint256ArraysMock, [EVEN_ELEMENTS_ARRAY]);
return { arrays };
}

beforeEach(async function () {
this.arrays = await Uint256ArraysMock.new(EVEN_ELEMENTS_ARRAY);
Object.assign(this, await loadFixture(fixture));
});

it('returns correct index for the basic case', async function () {
expect(await this.arrays.findUpperBound(16)).to.be.bignumber.equal('5');
expect(await this.arrays.findUpperBound(16)).to.be.equal('5');
});

it('returns 0 for the first element', async function () {
expect(await this.arrays.findUpperBound(11)).to.be.bignumber.equal('0');
expect(await this.arrays.findUpperBound(11)).to.be.equal('0');
});

it('returns index of the last element', async function () {
expect(await this.arrays.findUpperBound(20)).to.be.bignumber.equal('9');
expect(await this.arrays.findUpperBound(20)).to.be.equal('9');
});

it('returns first index after last element if searched value is over the upper boundary', async function () {
expect(await this.arrays.findUpperBound(32)).to.be.bignumber.equal('10');
expect(await this.arrays.findUpperBound(32)).to.be.equal('10');
});

it('returns 0 for the element under the lower boundary', async function () {
expect(await this.arrays.findUpperBound(2)).to.be.bignumber.equal('0');
expect(await this.arrays.findUpperBound(2)).to.be.equal('0');
});
});

context('Odd number of elements', function () {
describe('Odd number of elements', function () {
const ODD_ELEMENTS_ARRAY = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21];

const fixture = async () => {
const arrays = await ethers.deployContract(Uint256ArraysMock, [ODD_ELEMENTS_ARRAY]);
return { arrays };
}

beforeEach(async function () {
this.arrays = await Uint256ArraysMock.new(ODD_ELEMENTS_ARRAY);
Object.assign(this, await loadFixture(fixture));
});

it('returns correct index for the basic case', async function () {
expect(await this.arrays.findUpperBound(16)).to.be.bignumber.equal('5');
expect(await this.arrays.findUpperBound(16)).to.be.equal('5');
});

it('returns 0 for the first element', async function () {
expect(await this.arrays.findUpperBound(11)).to.be.bignumber.equal('0');
expect(await this.arrays.findUpperBound(11)).to.be.equal('0');
});

it('returns index of the last element', async function () {
expect(await this.arrays.findUpperBound(21)).to.be.bignumber.equal('10');
expect(await this.arrays.findUpperBound(21)).to.be.equal('10');
});

it('returns first index after last element if searched value is over the upper boundary', async function () {
expect(await this.arrays.findUpperBound(32)).to.be.bignumber.equal('11');
expect(await this.arrays.findUpperBound(32)).to.be.equal('11');
});

it('returns 0 for the element under the lower boundary', async function () {
expect(await this.arrays.findUpperBound(2)).to.be.bignumber.equal('0');
expect(await this.arrays.findUpperBound(2)).to.be.equal('0');
});
});

context('Array with gap', function () {
describe('Array with gap', function () {
const WITH_GAP_ARRAY = [11, 12, 13, 14, 15, 20, 21, 22, 23, 24];

const fixture = async () => {
const arrays = await ethers.deployContract(Uint256ArraysMock, [WITH_GAP_ARRAY]);
return { arrays };
}

beforeEach(async function () {
this.arrays = await Uint256ArraysMock.new(WITH_GAP_ARRAY);
Object.assign(this, await loadFixture(fixture));
});

it('returns index of first element in next filled range', async function () {
expect(await this.arrays.findUpperBound(17)).to.be.bignumber.equal('5');
expect(await this.arrays.findUpperBound(17)).to.be.equal('5');
});
});

context('Empty array', function () {
beforeEach(async function () {
this.arrays = await Uint256ArraysMock.new([]);
this.arrays = await ethers.deployContract(Uint256ArraysMock, [[]]);
});

it('always returns 0 for empty array', async function () {
expect(await this.arrays.findUpperBound(10)).to.be.bignumber.equal('0');
expect(await this.arrays.findUpperBound(10)).to.be.equal('0');
});
});
});
Expand All @@ -94,28 +112,30 @@ contract('Arrays', function () {
artifact: AddressArraysMock,
elements: Array(10)
.fill()
.map(() => web3.utils.randomHex(20)),
.map(() => randomHex(20))
},
{
type: 'bytes32',
artifact: Bytes32ArraysMock,
elements: Array(10)
.fill()
.map(() => web3.utils.randomHex(32)),
.map(() => randomHex(32)),
},
{
type: 'uint256',
artifact: Uint256ArraysMock,
elements: Array(10)
.fill()
.map(() => web3.utils.randomHex(32)),
.map(() => randomHex(32)),
},
]) {
it(type, async function () {
const contract = await artifact.new(elements);
const contract = await ethers.deployContract(artifact, [elements]);

for (const i in elements) {
expect(await contract.unsafeAccess(i)).to.be.bignumber.equal(elements[i]);
expect(await contract.unsafeAccess(i)).to.be.equal(
type == 'address' ? ethers.getAddress(elements[i]) : elements[i]
)
}
});
}
Expand Down