Skip to content

Commit 10f7e81

Browse files
committed
Update in response to review comments
1 parent 082e3f0 commit 10f7e81

2 files changed

Lines changed: 73 additions & 24 deletions

File tree

contracts/extensions/Korporatio.sol

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,14 @@ contract Korporatio is ColonyExtensionMeta {
2929

3030
// Constants
3131

32-
uint256 constant APPLICATION_FEE = 6500 * WAD;
33-
3432
// Events
3533

3634
event ApplicationCreated(uint256 indexed stakeId, address indexed applicant);
3735
event ApplicationCancelled(uint256 indexed stakeId);
3836
event StakeReclaimed(uint256 indexed stakeId);
3937
event StakeSlashed(uint256 indexed stakeId);
4038
event ApplicationUpdated(uint256 indexed stakeId, bytes32 ipfsHash);
41-
event ApplicationSubmitted(uint256 indexed stakeId, bytes32 ipfsHash);
39+
event ApplicationSubmitted(uint256 indexed stakeId);
4240

4341
// Data structures
4442

@@ -62,6 +60,11 @@ contract Korporatio is ColonyExtensionMeta {
6260

6361
// Modifiers
6462

63+
modifier onlyApplicant(uint256 _applicationId) {
64+
require(msgSender() == applications[_applicationId].applicant, "korporatio-not-applicant");
65+
_;
66+
}
67+
6568
// Overrides
6669

6770
/// @notice Returns the identifier of the extension
@@ -106,6 +109,7 @@ contract Korporatio is ColonyExtensionMeta {
106109
)
107110
public
108111
{
112+
require(numApplications <= 0, "korporatio-cannot-initialise");
109113
require(
110114
colony.hasUserRole(msgSender(), 1, ColonyDataTypes.ColonyRole.Architecture),
111115
"korporatio-not-root-architect"
@@ -130,6 +134,8 @@ contract Korporatio is ColonyExtensionMeta {
130134
public
131135
notDeprecated
132136
{
137+
require(paymentToken != address(0x0), "korporatio-not-initialised");
138+
133139
bytes32 rootHash = IColonyNetwork(colonyNetworkAddress).getReputationRootHash();
134140
uint256 rootSkillId = colony.getDomain(1).skillId;
135141

@@ -166,21 +172,18 @@ contract Korporatio is ColonyExtensionMeta {
166172
emit ApplicationCreated(numApplications, msgSender());
167173
}
168174

169-
function cancelApplication(uint256 _applicationId) public {
170-
require(applications[_applicationId].applicant == msgSender(), "korporatio-cannot-cancel");
171-
175+
function cancelApplication(uint256 _applicationId) public onlyApplicant(_applicationId) {
172176
applications[_applicationId].cancelledAt = block.timestamp;
173177

174178
emit ApplicationCancelled(_applicationId);
175179
}
176180

177-
function reclaimStake(uint256 _applicationId) public {
178-
require(
179-
applications[_applicationId].cancelledAt + claimDelay <= block.timestamp,
180-
"korporatio-cannot-reclaim"
181-
);
181+
function reclaimStake(uint256 _applicationId) public onlyApplicant(_applicationId) {
182+
Application storage application = applications[_applicationId];
183+
require(application.applicant == msgSender(), "korporatio-not-applicant");
184+
require(application.cancelledAt + claimDelay <= block.timestamp, "korporatio-cannot-reclaim");
182185

183-
uint256 stakeAmount = applications[_applicationId].stakeAmount;
186+
uint256 stakeAmount = application.stakeAmount;
184187
delete applications[_applicationId];
185188

186189
colony.deobligateStake(msgSender(), 1, stakeAmount);
@@ -206,14 +209,13 @@ contract Korporatio is ColonyExtensionMeta {
206209
emit StakeSlashed(_applicationId);
207210
}
208211

209-
function updateApplication(uint256 _applicationId, bytes32 _ipfsHash) public {
210-
require(applications[_applicationId].applicant == msgSender(), "korporatio-not-applicant");
212+
function updateApplication(uint256 _applicationId, bytes32 _ipfsHash) public onlyApplicant(_applicationId) {
211213
require(applications[_applicationId].cancelledAt == UINT256_MAX, "korporatio-stake-cancelled");
212214

213215
emit ApplicationUpdated(_applicationId, _ipfsHash);
214216
}
215217

216-
function submitApplication(uint256 _applicationId, bytes32 _ipfsHash) public {
218+
function submitApplication(uint256 _applicationId) public {
217219
require(colony.hasUserRole(msgSender(), 1, ColonyDataTypes.ColonyRole.Root), "korporatio-caller-not-root");
218220
require(applications[_applicationId].cancelledAt == UINT256_MAX, "korporatio-stake-cancelled");
219221

@@ -222,7 +224,7 @@ contract Korporatio is ColonyExtensionMeta {
222224
address metaColony = IColonyNetwork(colonyNetworkAddress).getMetaColony();
223225
require(ERC20(paymentToken).transferFrom(msgSender(), metaColony, applicationFee), "korporatio-transfer-failed");
224226

225-
emit ApplicationSubmitted(_applicationId, _ipfsHash);
227+
emit ApplicationSubmitted(_applicationId);
226228
}
227229

228230
// View

test/extensions/korporatio.js

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* globals artifacts */
22

3+
const { BN } = require("bn.js");
34
const chai = require("chai");
45
const bnChai = require("bn-chai");
56
const { ethers } = require("ethers");
@@ -168,13 +169,38 @@ contract("Korporatio", (accounts) => {
168169
await checkErrorRevert(korporatio.deprecate(true, { from: USER1 }), "ds-auth-unauthorized");
169170
await checkErrorRevert(korporatio.uninstall({ from: USER1 }), "ds-auth-unauthorized");
170171
});
172+
173+
it("cannot create applications unless initialised", async () => {
174+
await checkErrorRevert(
175+
korporatio.createApplication(domain1Key, domain1Value, domain1Mask, domain1Siblings, user0Key, user0Value, user0Mask, user0Siblings, {
176+
from: USER0,
177+
}),
178+
"korporatio-not-initialised"
179+
);
180+
});
171181
});
172182

173183
describe("creating applications", async () => {
174184
beforeEach(async () => {
185+
await colony.approveStake(korporatio.address, 1, WAD, { from: USER0 });
186+
175187
await korporatio.initialise(token.address, APPLICATION_FEE, WAD.divn(100), SECONDS_PER_DAY, { from: USER0 });
188+
});
176189

177-
await colony.approveStake(korporatio.address, 1, WAD, { from: USER0 });
190+
it("can re-initialise until first application is created", async () => {
191+
await korporatio.initialise(token.address, APPLICATION_FEE, WAD.divn(10), SECONDS_PER_DAY, { from: USER0 });
192+
193+
const stakeFraction = await korporatio.getStakeFraction();
194+
expect(stakeFraction).to.eq.BN(WAD.divn(10));
195+
196+
await korporatio.createApplication(domain1Key, domain1Value, domain1Mask, domain1Siblings, user0Key, user0Value, user0Mask, user0Siblings, {
197+
from: USER0,
198+
});
199+
200+
await checkErrorRevert(
201+
korporatio.initialise(token.address, APPLICATION_FEE, WAD.divn(100), SECONDS_PER_DAY, { from: USER1 }),
202+
"korporatio-cannot-initialise"
203+
);
178204
});
179205

180206
it("can query for configuration params", async () => {
@@ -256,7 +282,7 @@ contract("Korporatio", (accounts) => {
256282
const applicationId = await korporatio.getNumApplications();
257283

258284
// Only applicant can cancel
259-
await checkErrorRevert(korporatio.cancelApplication(applicationId, { from: USER1 }), "korporatio-cannot-cancel");
285+
await checkErrorRevert(korporatio.cancelApplication(applicationId, { from: USER1 }), "korporatio-not-applicant");
260286

261287
const tx = await korporatio.cancelApplication(applicationId, { from: USER0 });
262288
const blockTime = await getBlockTime(tx.receipt.blockNumber);
@@ -278,7 +304,7 @@ contract("Korporatio", (accounts) => {
278304

279305
await forwardTime(SECONDS_PER_DAY, this);
280306

281-
await korporatio.reclaimStake(applicationId);
307+
await korporatio.reclaimStake(applicationId, { from: USER0 });
282308

283309
const obligation = await colony.getObligation(USER0, korporatio.address, 1);
284310
expect(obligation).to.be.zero;
@@ -355,20 +381,41 @@ contract("Korporatio", (accounts) => {
355381
await korporatio.createFreeApplication({ from: USER0 });
356382

357383
const applicationId = await korporatio.getNumApplications();
358-
const ipfsHash = soliditySha3("IPFS Hash");
359384

360385
// Cannot submit if not root
361-
await checkErrorRevert(korporatio.submitApplication(applicationId, ipfsHash, { from: USER1 }), "korporatio-caller-not-root");
386+
await checkErrorRevert(korporatio.submitApplication(applicationId, { from: USER1 }), "korporatio-caller-not-root");
362387

363-
const tx = await korporatio.submitApplication(applicationId, ipfsHash, { from: USER0 });
364-
await expectEvent(tx, "ApplicationSubmitted", [applicationId, ipfsHash]);
388+
const tx = await korporatio.submitApplication(applicationId, { from: USER0 });
389+
await expectEvent(tx, "ApplicationSubmitted", [applicationId]);
365390

366391
const metaColonyAddress = await colonyNetwork.getMetaColony();
367392
const metaColonyBalance = await token.balanceOf(metaColonyAddress);
368393
expect(metaColonyBalance).to.eq.BN(APPLICATION_FEE);
369394

370395
// Cannot submit once cancelled
371-
await checkErrorRevert(korporatio.submitApplication(applicationId, ipfsHash, { from: USER0 }), "korporatio-stake-cancelled");
396+
await checkErrorRevert(korporatio.submitApplication(applicationId, { from: USER0 }), "korporatio-stake-cancelled");
397+
});
398+
399+
it("can reclaim a stake via arbitration if the extension is deleted", async () => {
400+
const korporatioAddress = korporatio.address;
401+
await korporatio.createApplication(domain1Key, domain1Value, domain1Mask, domain1Siblings, user0Key, user0Value, user0Mask, user0Siblings, {
402+
from: USER0,
403+
});
404+
405+
const lockPre = await tokenLocking.getUserLock(token.address, USER0);
406+
const obligationPre = await colony.getObligation(USER0, korporatioAddress, 1);
407+
expect(obligationPre).to.eq.BN(WAD.divn(100).muln(3));
408+
409+
await colony.uninstallExtension(KORPORATIO, { from: USER0 });
410+
411+
await colony.transferStake(1, UINT256_MAX, korporatioAddress, USER0, 1, obligationPre, USER0, { from: USER1 });
412+
413+
const lockPost = await tokenLocking.getUserLock(token.address, USER0);
414+
const obligationPost = await colony.getObligation(USER0, korporatioAddress, 1);
415+
416+
// Obligation is zeroed out, but token balance is unchanged
417+
expect(obligationPost).to.be.zero;
418+
expect(new BN(lockPre.balance)).to.eq.BN(lockPost.balance);
372419
});
373420

374421
it("can submit a stake via metatransactions", async () => {

0 commit comments

Comments
 (0)