Skip to content

Commit

Permalink
test: removed majority voting base tests and fixed 165 tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jordaniza committed Jun 5, 2024
1 parent f980891 commit 47bcc41
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 250 deletions.
4 changes: 4 additions & 0 deletions packages/contracts/src/ITokenVoting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol";
import {IVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol";
import {IMembership} from "@aragon/osx-commons-contracts/src/plugin/extensions/membership/IMembership.sol";

Check warning on line 6 in packages/contracts/src/ITokenVoting.sol

View workflow job for this annotation

GitHub Actions / checks

imported name IMembership is not used

/// @title ITokenVoting
/// @author Aragon X - 2024
/// @notice Interface for Aragon IVotes-based voting and proposal plugin "TokenVoting".
/// @custom:security-contact [email protected]
interface ITokenVoting {
/// @notice Vote options that a voter can chose from.
/// @param None The default option state of a voter indicating the absence from the vote.
Expand Down
12 changes: 7 additions & 5 deletions packages/contracts/src/TokenVoting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20

import {IMembership} from "@aragon/osx-commons-contracts/src/plugin/extensions/membership/IMembership.sol";
import {_applyRatioCeiled} from "@aragon/osx-commons-contracts/src/utils/math/Ratio.sol";
import {IProtocolVersion} from "@aragon/osx-commons-contracts/src/utils/versioning/IProtocolVersion.sol";

Check warning on line 11 in packages/contracts/src/TokenVoting.sol

View workflow job for this annotation

GitHub Actions / checks

imported name IProtocolVersion is not used

import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol";

Expand Down Expand Up @@ -41,11 +42,9 @@ contract TokenVoting is

/// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract.
bytes4 internal constant TOKEN_VOTING_INTERFACE_ID =
this.initialize.selector ^ this.getVotingToken.selector;

/// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract.
bytes4 internal constant MAJORITY_VOTING_BASE_INTERFACE_ID =
this.minDuration.selector ^
this.initialize.selector ^
this.getVotingToken.selector ^
this.minDuration.selector ^
this.minProposerVotingPower.selector ^
this.votingMode.selector ^
this.totalVotingPower.selector ^
Expand Down Expand Up @@ -143,6 +142,8 @@ contract TokenVoting is
emit MembershipContractAnnounced({definingContract: address(_token)});
}

function v2() external {}

Check warning on line 145 in packages/contracts/src/TokenVoting.sol

View workflow job for this annotation

GitHub Actions / checks

Code contains empty blocks

/// @notice Checks if this or the parent contract supports an interface by its ID.
/// @param _interfaceId The ID of the interface.
/// @return Returns `true` if the interface is supported.
Expand All @@ -158,6 +159,7 @@ contract TokenVoting is
return
_interfaceId == TOKEN_VOTING_INTERFACE_ID ||
_interfaceId == type(IMembership).interfaceId ||
_interfaceId == type(ITokenVoting).interfaceId ||
super.supportsInterface(_interfaceId);
}

Expand Down
62 changes: 2 additions & 60 deletions packages/contracts/test/10_unit-testing/11_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
IProtocolVersion__factory,
ProxyFactory__factory,
} from '../../typechain';
import {ITokenVoting as MajorityVotingBase} from '../../typechain';
import {ProxyCreatedEvent} from '../../typechain/@aragon/osx-commons-contracts/src/utils/deployment/ProxyFactory';
import {MajorityVotingBase} from '../../typechain/src/MajorityVotingBase';
import {
ProposalCreatedEvent,
ProposalExecutedEvent,
Expand Down Expand Up @@ -276,64 +276,6 @@ describe('TokenVoting', function () {
});
});

describe('ERC-165', async () => {
it('does not support the empty interface', async () => {
const {initializedPlugin: plugin} = await loadFixture(globalFixture);
expect(await plugin.supportsInterface('0xffffffff')).to.be.false;
});

it('supports the `IERC165Upgradeable` interface', async () => {
const {initializedPlugin: plugin} = await loadFixture(globalFixture);
const iface = IERC165Upgradeable__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IPlugin` interface', async () => {
const {initializedPlugin: plugin} = await loadFixture(globalFixture);
const iface = IPlugin__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IProtocolVersion` interface', async () => {
const {initializedPlugin: plugin} = await loadFixture(globalFixture);
const iface = IProtocolVersion__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IProposal` interface', async () => {
const {initializedPlugin: plugin} = await loadFixture(globalFixture);
const iface = IProposal__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IMembership` interface', async () => {
const {initializedPlugin: plugin} = await loadFixture(globalFixture);
const iface = IMembership__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IMajorityVoting` interface', async () => {
const {initializedPlugin: plugin} = await loadFixture(globalFixture);
const iface = IMajorityVoting__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `MajorityVotingBase` interface', async () => {
const {initializedPlugin: plugin} = await loadFixture(globalFixture);
expect(
await plugin.supportsInterface(
getInterfaceId(MAJORITY_VOTING_BASE_INTERFACE)
)
).to.be.true;
});

it('supports the `TokenVoting` interface', async () => {
const {initializedPlugin: plugin} = await loadFixture(globalFixture);
const interfaceId = getInterfaceId(TOKEN_VOTING_INTERFACE);
expect(await plugin.supportsInterface(interfaceId)).to.be.true;
});
});

describe('isMember', async () => {
it('returns true if the account currently owns at least one token', async () => {
const {alice, bob, initializedPlugin, token} = await loadFixture(
Expand Down Expand Up @@ -762,7 +704,7 @@ describe('TokenVoting', function () {
{
receiver: bob.address,
amount:
voteSettingsWithMinProposerVotingPower.minProposerVotingPower,
voteSettingsWithMinProposerVotingPower.minProposerVotingPower as BigNumber,
},
]);

Expand Down
105 changes: 105 additions & 0 deletions packages/contracts/test/10_unit-testing/13_Interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {createDaoProxy} from '../20_integration-testing/test-helpers';
import {
IERC165Upgradeable__factory,
IPlugin__factory,
IProposal__factory,
IProtocolVersion__factory,
ProxyFactory__factory,
ITokenVoting__factory,
ITokenVoting,
} from '../../typechain';
import {ProxyCreatedEvent} from '../../typechain/@aragon/osx-commons-contracts/src/utils/deployment/ProxyFactory';
import {IMembership__factory} from '../../typechain/factories/@aragon/osx-v1.0.0/core/plugin/membership';
import {TOKEN_VOTING_INTERFACE} from '../test-utils/token-voting-constants';
import {
TokenVoting,
TokenVoting__factory,
} from '../test-utils/typechain-versions';
import {VotingMode} from '../test-utils/voting-helpers';
import {TIME, findEvent} from '@aragon/osx-commons-sdk';
import {getInterfaceId} from '@aragon/osx-commons-sdk';
import {pctToRatio} from '@aragon/osx-commons-sdk';
import {DAO} from '@aragon/osx-ethers';
import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers';
import {expect} from 'chai';
import {ethers} from 'hardhat';

describe('ERC-165', async () => {
let signers: SignerWithAddress[];
let deployer: SignerWithAddress;
let plugin: TokenVoting;
let dao: DAO;
let votingSettings: ITokenVoting.VotingSettingsStruct;

before(async () => {
signers = await ethers.getSigners();
deployer = signers[0];

dao = await createDaoProxy(signers[0], '0x00');
});

beforeEach(async () => {
votingSettings = {
votingMode: VotingMode.EarlyExecution,
supportThreshold: pctToRatio(50),
minParticipation: pctToRatio(20),
minDuration: TIME.HOUR,
minProposerVotingPower: 0,
};

const pluginImplementation = await new TokenVoting__factory(
signers[0]
).deploy();
const proxyFactory = await new ProxyFactory__factory(deployer).deploy(
pluginImplementation.address
);
const deploymentTx1 = await proxyFactory.deployUUPSProxy([]);
const proxyCreatedEvent1 = findEvent<ProxyCreatedEvent>(
await deploymentTx1.wait(),
proxyFactory.interface.getEvent('ProxyCreated').name
);
plugin = TokenVoting__factory.connect(
proxyCreatedEvent1.args.proxy,
deployer
);
});

it('does not support the empty interface', async () => {
expect(await plugin.supportsInterface('0xffffffff')).to.be.false;
});

it('supports the `IERC165Upgradeable` interface', async () => {
const iface = IERC165Upgradeable__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IPlugin` interface', async () => {
const iface = IPlugin__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IProtocolVersion` interface', async () => {
const iface = IProtocolVersion__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IProposal` interface', async () => {
const iface = IProposal__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `ITokenVoting` interface', async () => {
const iface = ITokenVoting__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IMembership` interface', async () => {
const iface = IMembership__factory.createInterface();
expect(await plugin.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `TokenVoting` interface', async () => {
const interfaceId = getInterfaceId(TOKEN_VOTING_INTERFACE);
expect(await plugin.supportsInterface(interfaceId)).to.be.true;
});
});
128 changes: 128 additions & 0 deletions packages/contracts/test/10_unit-testing/14_update-settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import {createDaoProxy} from '../20_integration-testing/test-helpers';
import {
IERC165Upgradeable__factory,
IPlugin__factory,
IProposal__factory,
IProtocolVersion__factory,
ProxyFactory__factory,
ITokenVoting__factory,
ITokenVoting,
} from '../../typechain';
import {ProxyCreatedEvent} from '../../typechain/@aragon/osx-commons-contracts/src/utils/deployment/ProxyFactory';
import {
TokenVoting,
TokenVoting__factory,
} from '../test-utils/typechain-versions';
import {VotingMode} from '../test-utils/voting-helpers';
import {TIME, findEvent} from '@aragon/osx-commons-sdk';
import {pctToRatio} from '@aragon/osx-commons-sdk';
import {DAO} from '@aragon/osx-ethers';
import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers';
import {expect} from 'chai';
import {ethers} from 'hardhat';

describe('updateVotingSettings', async () => {
let signers: SignerWithAddress[];
let deployer: SignerWithAddress;
let votingBase: TokenVoting;
let dao: DAO;
const mockTokenAddress = ethers.constants.AddressZero;
let votingSettings: ITokenVoting.VotingSettingsStruct;

before(async () => {
signers = await ethers.getSigners();
deployer = signers[0];
dao = await createDaoProxy(signers[0], '0x00');
});

beforeEach(async () => {
votingSettings = {
votingMode: VotingMode.EarlyExecution,
supportThreshold: pctToRatio(50),
minParticipation: pctToRatio(20),
minDuration: TIME.HOUR,
minProposerVotingPower: 0,
};

const pluginImplementation = await new TokenVoting__factory(
signers[0]
).deploy();
const proxyFactory = await new ProxyFactory__factory(deployer).deploy(
pluginImplementation.address
);
const deploymentTx1 = await proxyFactory.deployUUPSProxy([]);
const proxyCreatedEvent1 = findEvent<ProxyCreatedEvent>(
await deploymentTx1.wait(),
proxyFactory.interface.getEvent('ProxyCreated').name
);
votingBase = TokenVoting__factory.connect(
proxyCreatedEvent1.args.proxy,
deployer
);

await dao.grant(
votingBase.address,
deployer.address,
ethers.utils.id('UPDATE_VOTING_SETTINGS_PERMISSION')
);
});

beforeEach(async () => {
await votingBase.initialize(dao.address, votingSettings, mockTokenAddress);
});

it('reverts if the support threshold specified equals 100%', async () => {
votingSettings.supportThreshold = pctToRatio(100);
await expect(votingBase.updateVotingSettings(votingSettings))
.to.be.revertedWithCustomError(votingBase, 'RatioOutOfBounds')
.withArgs(pctToRatio(100).sub(1), votingSettings.supportThreshold);
});

it('reverts if the support threshold specified exceeds 100%', async () => {
votingSettings.supportThreshold = pctToRatio(1000);
await expect(votingBase.updateVotingSettings(votingSettings))
.to.be.revertedWithCustomError(votingBase, 'RatioOutOfBounds')
.withArgs(pctToRatio(100).sub(1), votingSettings.supportThreshold);
});

it('reverts if the support threshold specified equals 100%', async () => {
votingSettings.supportThreshold = pctToRatio(1000);
await expect(votingBase.updateVotingSettings(votingSettings))
.to.be.revertedWithCustomError(votingBase, 'RatioOutOfBounds')
.withArgs(pctToRatio(100).sub(1), votingSettings.supportThreshold);
});

it('reverts if the minimum participation specified exceeds 100%', async () => {
votingSettings.minParticipation = pctToRatio(1000);

await expect(votingBase.updateVotingSettings(votingSettings))
.to.be.revertedWithCustomError(votingBase, 'RatioOutOfBounds')
.withArgs(pctToRatio(100), votingSettings.minParticipation);
});

it('reverts if the minimal duration is shorter than one hour', async () => {
votingSettings.minDuration = TIME.HOUR - 1;
await expect(votingBase.updateVotingSettings(votingSettings))
.to.be.revertedWithCustomError(votingBase, 'MinDurationOutOfBounds')
.withArgs(TIME.HOUR, votingSettings.minDuration);
});

it('reverts if the minimal duration is longer than one year', async () => {
votingSettings.minDuration = TIME.YEAR + 1;
await expect(votingBase.updateVotingSettings(votingSettings))
.to.be.revertedWithCustomError(votingBase, 'MinDurationOutOfBounds')
.withArgs(TIME.YEAR, votingSettings.minDuration);
});

it('should change the voting settings successfully', async () => {
await expect(votingBase.updateVotingSettings(votingSettings))
.to.emit(votingBase, 'VotingSettingsUpdated')
.withArgs(
votingSettings.votingMode,
votingSettings.supportThreshold,
votingSettings.minParticipation,
votingSettings.minDuration,
votingSettings.minProposerVotingPower
);
});
});
Loading

0 comments on commit 47bcc41

Please sign in to comment.