@ballkidz/defifa 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/STYLE_GUIDE.md +14 -1
- package/package.json +7 -5
- package/script/Deploy.s.sol +13 -11
- package/script/helpers/DefifaDeploymentLib.sol +25 -7
- package/src/DefifaDeployer.sol +15 -6
- package/src/DefifaGovernor.sol +5 -5
- package/src/DefifaHook.sol +22 -16
- package/src/DefifaTokenUriResolver.sol +3 -2
- package/src/libraries/DefifaHookLib.sol +5 -3
package/STYLE_GUIDE.md
CHANGED
|
@@ -253,9 +253,12 @@ uint256 public constant MAX_RESERVED_PERCENT = 10_000;
|
|
|
253
253
|
|
|
254
254
|
## Function Calls
|
|
255
255
|
|
|
256
|
-
Use named
|
|
256
|
+
Use named arguments for all function calls with 2 or more arguments — in both `src/` and `script/`:
|
|
257
257
|
|
|
258
258
|
```solidity
|
|
259
|
+
// Good — named arguments
|
|
260
|
+
token.mint({account: beneficiary, amount: count});
|
|
261
|
+
_transferOwnership({newOwner: address(0), projectId: 0});
|
|
259
262
|
PERMISSIONS.hasPermission({
|
|
260
263
|
operator: sender,
|
|
261
264
|
account: account,
|
|
@@ -264,8 +267,18 @@ PERMISSIONS.hasPermission({
|
|
|
264
267
|
includeRoot: true,
|
|
265
268
|
includeWildcardProjectId: true
|
|
266
269
|
});
|
|
270
|
+
|
|
271
|
+
// Bad — positional arguments with 2+ args
|
|
272
|
+
token.mint(beneficiary, count);
|
|
273
|
+
_transferOwnership(address(0), 0);
|
|
267
274
|
```
|
|
268
275
|
|
|
276
|
+
Single-argument calls use positional style: `_burn(amount)`.
|
|
277
|
+
|
|
278
|
+
This also applies to constructor calls, struct literals, and inherited/library calls (e.g., OZ `_mint`, `_safeMint`, `safeTransfer`, `allowance`, `Clones.cloneDeterministic`).
|
|
279
|
+
|
|
280
|
+
Named argument keys must use **camelCase** — never underscores. If a function's parameter names use underscores, rename them to camelCase first.
|
|
281
|
+
|
|
269
282
|
## Multiline Signatures
|
|
270
283
|
|
|
271
284
|
```solidity
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ballkidz/defifa",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.0.0"
|
|
@@ -13,12 +13,14 @@
|
|
|
13
13
|
"url": "https://github.com/BallKidz/defifa-collection-deployer"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@bananapus/721-hook-v6": "^0.0.
|
|
17
|
-
"@bananapus/address-registry-v6": "^0.0.
|
|
18
|
-
"@bananapus/core-v6": "^0.0.
|
|
19
|
-
"@bananapus/permission-ids-v6": "^0.0.
|
|
16
|
+
"@bananapus/721-hook-v6": "^0.0.16",
|
|
17
|
+
"@bananapus/address-registry-v6": "^0.0.9",
|
|
18
|
+
"@bananapus/core-v6": "^0.0.16",
|
|
19
|
+
"@bananapus/permission-ids-v6": "^0.0.9",
|
|
20
|
+
"@croptop/core-v6": "^0.0.15",
|
|
20
21
|
"@openzeppelin/contracts": "^5.6.1",
|
|
21
22
|
"@prb/math": "^4.1.1",
|
|
23
|
+
"@rev-net/core-v6": "^0.0.12",
|
|
22
24
|
"scripty.sol": "^2.1.1"
|
|
23
25
|
},
|
|
24
26
|
"devDependencies": {
|
package/script/Deploy.s.sol
CHANGED
|
@@ -91,18 +91,20 @@ contract DeployMainnet is Script, Sphinx {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
function deploy() public sphinx {
|
|
94
|
-
DefifaHook hook = new DefifaHook{salt: _salt}(
|
|
94
|
+
DefifaHook hook = new DefifaHook{salt: _salt}({
|
|
95
|
+
_directory: core.directory, _defifaToken: defifaToken, _baseProtocolToken: baseProtocolToken
|
|
96
|
+
});
|
|
95
97
|
DefifaTokenUriResolver tokenUriResolver = new DefifaTokenUriResolver{salt: _salt}(_typeface);
|
|
96
|
-
DefifaGovernor governor = new DefifaGovernor{salt: _salt}(core.controller, safeAddress());
|
|
97
|
-
DefifaDeployer deployer = new DefifaDeployer{salt: _salt}(
|
|
98
|
-
address(hook),
|
|
99
|
-
tokenUriResolver,
|
|
100
|
-
governor,
|
|
101
|
-
core.controller,
|
|
102
|
-
registry.registry,
|
|
103
|
-
_defifaProjectId,
|
|
104
|
-
_baseProtocolProjectId
|
|
105
|
-
);
|
|
98
|
+
DefifaGovernor governor = new DefifaGovernor{salt: _salt}({_controller: core.controller, _owner: safeAddress()});
|
|
99
|
+
DefifaDeployer deployer = new DefifaDeployer{salt: _salt}({
|
|
100
|
+
_hookCodeOrigin: address(hook),
|
|
101
|
+
_tokenUriResolver: tokenUriResolver,
|
|
102
|
+
_governor: governor,
|
|
103
|
+
_controller: core.controller,
|
|
104
|
+
_registry: registry.registry,
|
|
105
|
+
_defifaProjectId: _defifaProjectId,
|
|
106
|
+
_baseProtocolProjectId: _baseProtocolProjectId
|
|
107
|
+
});
|
|
106
108
|
|
|
107
109
|
governor.transferOwnership(address(deployer));
|
|
108
110
|
}
|
|
@@ -34,7 +34,7 @@ library DefifaDeploymentLib {
|
|
|
34
34
|
|
|
35
35
|
for (uint256 _i; _i < networks.length; _i++) {
|
|
36
36
|
if (networks[_i].chainId == chainId) {
|
|
37
|
-
return getDeployment(path, networks[_i].name);
|
|
37
|
+
return getDeployment({path: path, network_name: networks[_i].name});
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -49,14 +49,32 @@ library DefifaDeploymentLib {
|
|
|
49
49
|
view
|
|
50
50
|
returns (DefifaDeployment memory deployment)
|
|
51
51
|
{
|
|
52
|
-
deployment.hook = DefifaHook(
|
|
52
|
+
deployment.hook = DefifaHook(
|
|
53
|
+
_getDeploymentAddress({
|
|
54
|
+
path: path, project_name: PROJECT_NAME, network_name: network_name, contractName: "DefifaHook"
|
|
55
|
+
})
|
|
56
|
+
);
|
|
53
57
|
|
|
54
|
-
deployment.deployer = DefifaDeployer(
|
|
58
|
+
deployment.deployer = DefifaDeployer(
|
|
59
|
+
_getDeploymentAddress({
|
|
60
|
+
path: path, project_name: PROJECT_NAME, network_name: network_name, contractName: "DefifaDeployer"
|
|
61
|
+
})
|
|
62
|
+
);
|
|
55
63
|
|
|
56
|
-
deployment.governor = DefifaGovernor(
|
|
64
|
+
deployment.governor = DefifaGovernor(
|
|
65
|
+
_getDeploymentAddress({
|
|
66
|
+
path: path, project_name: PROJECT_NAME, network_name: network_name, contractName: "DefifaGovernor"
|
|
67
|
+
})
|
|
68
|
+
);
|
|
57
69
|
|
|
58
|
-
deployment.tokenUriResolver =
|
|
59
|
-
|
|
70
|
+
deployment.tokenUriResolver = DefifaTokenUriResolver(
|
|
71
|
+
_getDeploymentAddress({
|
|
72
|
+
path: path,
|
|
73
|
+
project_name: PROJECT_NAME,
|
|
74
|
+
network_name: network_name,
|
|
75
|
+
contractName: "DefifaTokenUriResolver"
|
|
76
|
+
})
|
|
77
|
+
);
|
|
60
78
|
}
|
|
61
79
|
|
|
62
80
|
/// @notice Get the address of a contract that was deployed by the Deploy script.
|
|
@@ -78,6 +96,6 @@ library DefifaDeploymentLib {
|
|
|
78
96
|
{
|
|
79
97
|
string memory deploymentJson =
|
|
80
98
|
vm.readFile(string.concat(path, project_name, "/", network_name, "/", contractName, ".json"));
|
|
81
|
-
return stdJson.readAddress(deploymentJson, ".address");
|
|
99
|
+
return stdJson.readAddress({json: deploymentJson, key: ".address"});
|
|
82
100
|
}
|
|
83
101
|
}
|
package/src/DefifaDeployer.sol
CHANGED
|
@@ -323,7 +323,8 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
|
|
|
323
323
|
if (_pot == 0) revert DefifaDeployer_NothingToFulfill();
|
|
324
324
|
|
|
325
325
|
// Compute the fee amount based on the total absolute split percent stored at game creation.
|
|
326
|
-
uint256 _feeAmount =
|
|
326
|
+
uint256 _feeAmount =
|
|
327
|
+
mulDiv({x: _pot, y: _commitmentPercentOf[gameId], denominator: JBConstants.SPLITS_TOTAL_PERCENT});
|
|
327
328
|
|
|
328
329
|
// Store the actual fee amount for accurate currentGamePotOf reporting.
|
|
329
330
|
// Use max(feeAmount, 1) to preserve the reentrancy guard when pot is 0.
|
|
@@ -523,7 +524,9 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
|
|
|
523
524
|
// cloneDeterministic with msg.sender in the salt prevents this since a different
|
|
524
525
|
// caller produces a different address.
|
|
525
526
|
DefifaHook _hook = DefifaHook(
|
|
526
|
-
Clones.cloneDeterministic(
|
|
527
|
+
Clones.cloneDeterministic({
|
|
528
|
+
implementation: hookCodeOrigin, salt: keccak256(abi.encodePacked(msg.sender, _currentNonce))
|
|
529
|
+
})
|
|
527
530
|
);
|
|
528
531
|
|
|
529
532
|
// Use the default uri resolver if provided, else use the hardcoded generic default.
|
|
@@ -857,14 +860,20 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
|
|
|
857
860
|
uint256 _normalizedTotal;
|
|
858
861
|
for (uint256 _i; _i < _numberOfUserSplits; _i++) {
|
|
859
862
|
_splits[_i] = _initialSplits[_i];
|
|
860
|
-
_splits[_i].percent =
|
|
861
|
-
|
|
863
|
+
_splits[_i].percent = uint32(
|
|
864
|
+
mulDiv({
|
|
865
|
+
x: _initialSplits[_i].percent,
|
|
866
|
+
y: JBConstants.SPLITS_TOTAL_PERCENT,
|
|
867
|
+
denominator: _totalAbsolutePercent
|
|
868
|
+
})
|
|
869
|
+
);
|
|
862
870
|
_normalizedTotal += _splits[_i].percent;
|
|
863
871
|
}
|
|
864
872
|
|
|
865
873
|
// Add Defifa fee split (normalized).
|
|
866
|
-
uint256 _defifaNormalized =
|
|
867
|
-
|
|
874
|
+
uint256 _defifaNormalized = mulDiv({
|
|
875
|
+
x: _defifaAbsolutePercent, y: JBConstants.SPLITS_TOTAL_PERCENT, denominator: _totalAbsolutePercent
|
|
876
|
+
});
|
|
868
877
|
_splits[_numberOfUserSplits] = JBSplit({
|
|
869
878
|
preferAddToBalance: false,
|
|
870
879
|
percent: uint32(_defifaNormalized),
|
package/src/DefifaGovernor.sol
CHANGED
|
@@ -182,12 +182,12 @@ contract DefifaGovernor is Ownable, IDefifaGovernor {
|
|
|
182
182
|
// e.g. holding 3 of 10 tokens → 3/10 * MAX_ATTESTATION_POWER_TIER attestation power from this tier.
|
|
183
183
|
unchecked {
|
|
184
184
|
if (_tierAttestationUnitsForAccount != 0) {
|
|
185
|
-
attestationPower += mulDiv(
|
|
186
|
-
MAX_ATTESTATION_POWER_TIER,
|
|
187
|
-
_tierAttestationUnitsForAccount,
|
|
188
|
-
IDefifaHook(_metadata.dataHook)
|
|
185
|
+
attestationPower += mulDiv({
|
|
186
|
+
x: MAX_ATTESTATION_POWER_TIER,
|
|
187
|
+
y: _tierAttestationUnitsForAccount,
|
|
188
|
+
denominator: IDefifaHook(_metadata.dataHook)
|
|
189
189
|
.getPastTierTotalAttestationUnitsOf({tier: _tierId, timestamp: _timestamp})
|
|
190
|
-
);
|
|
190
|
+
});
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
}
|
package/src/DefifaHook.sol
CHANGED
|
@@ -266,8 +266,9 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
|
|
|
266
266
|
if (context.cashOutCount > 0) revert JB721Hook_UnexpectedTokenCashedOut();
|
|
267
267
|
|
|
268
268
|
// Fetch the cash out hook metadata using the corresponding metadata ID.
|
|
269
|
-
(bool metadataExists, bytes memory metadata) =
|
|
270
|
-
JBMetadataResolver.
|
|
269
|
+
(bool metadataExists, bytes memory metadata) = JBMetadataResolver.getDataFor({
|
|
270
|
+
id: JBMetadataResolver.getId({purpose: "cashOut", target: codeOrigin}), metadata: context.metadata
|
|
271
|
+
});
|
|
271
272
|
|
|
272
273
|
uint256[] memory decodedTokenIds;
|
|
273
274
|
|
|
@@ -283,7 +284,8 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
|
|
|
283
284
|
|
|
284
285
|
// Use this contract as the only cash out hook.
|
|
285
286
|
hookSpecifications = new JBCashOutHookSpecification[](1);
|
|
286
|
-
hookSpecifications[0] =
|
|
287
|
+
hookSpecifications[0] =
|
|
288
|
+
JBCashOutHookSpecification({hook: this, amount: 0, metadata: abi.encode(_cumulativeMintPrice)});
|
|
287
289
|
|
|
288
290
|
// Compute the cash out count based on the game phase.
|
|
289
291
|
cashOutCount = DefifaHookLib.computeCashOutCount({
|
|
@@ -573,7 +575,7 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
|
|
|
573
575
|
_tokenId = _tokenIds[_i];
|
|
574
576
|
|
|
575
577
|
// Mint the token.
|
|
576
|
-
_mint(_reservedTokenBeneficiary, _tokenId);
|
|
578
|
+
_mint({to: _reservedTokenBeneficiary, tokenId: _tokenId});
|
|
577
579
|
|
|
578
580
|
emit MintReservedToken(_tokenId, tierId, _reservedTokenBeneficiary, msg.sender);
|
|
579
581
|
|
|
@@ -614,9 +616,10 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
|
|
|
614
616
|
) revert JB721Hook_InvalidCashOut();
|
|
615
617
|
|
|
616
618
|
// Fetch the cash out hook metadata using the corresponding metadata ID.
|
|
617
|
-
(bool metadataExists, bytes memory metadata) = JBMetadataResolver.getDataFor(
|
|
618
|
-
JBMetadataResolver.getId("cashOut", METADATA_ID_TARGET),
|
|
619
|
-
|
|
619
|
+
(bool metadataExists, bytes memory metadata) = JBMetadataResolver.getDataFor({
|
|
620
|
+
id: JBMetadataResolver.getId({purpose: "cashOut", target: METADATA_ID_TARGET}),
|
|
621
|
+
metadata: context.cashOutMetadata
|
|
622
|
+
});
|
|
620
623
|
|
|
621
624
|
if (!metadataExists) {
|
|
622
625
|
revert();
|
|
@@ -865,7 +868,7 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
|
|
|
865
868
|
_tokenId = _tokenIds[_i];
|
|
866
869
|
|
|
867
870
|
// Mint the tokens.
|
|
868
|
-
_mint(_beneficiary, _tokenId);
|
|
871
|
+
_mint({to: _beneficiary, tokenId: _tokenId});
|
|
869
872
|
|
|
870
873
|
emit Mint(_tokenId, _mintTierIds[_i], _beneficiary, _amount, msg.sender);
|
|
871
874
|
|
|
@@ -889,8 +892,9 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
|
|
|
889
892
|
// Get the current amount for the sending delegate.
|
|
890
893
|
uint208 _current = _delegateTierCheckpoints[_from][_tierId].latest();
|
|
891
894
|
// Set the new amount for the sending delegate.
|
|
892
|
-
(uint256 _oldValue, uint256 _newValue) =
|
|
893
|
-
|
|
895
|
+
(uint256 _oldValue, uint256 _newValue) = _delegateTierCheckpoints[_from][_tierId].push({
|
|
896
|
+
key: uint48(block.timestamp), value: _current - uint208(_amount)
|
|
897
|
+
});
|
|
894
898
|
emit TierDelegateAttestationsChanged(_from, _tierId, _oldValue, _newValue, msg.sender);
|
|
895
899
|
}
|
|
896
900
|
|
|
@@ -899,8 +903,9 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
|
|
|
899
903
|
// Get the current amount for the receiving delegate.
|
|
900
904
|
uint208 _current = _delegateTierCheckpoints[_to][_tierId].latest();
|
|
901
905
|
// Set the new amount for the receiving delegate.
|
|
902
|
-
(uint256 _oldValue, uint256 _newValue) =
|
|
903
|
-
|
|
906
|
+
(uint256 _oldValue, uint256 _newValue) = _delegateTierCheckpoints[_to][_tierId].push({
|
|
907
|
+
key: uint48(block.timestamp), value: _current + uint208(_amount)
|
|
908
|
+
});
|
|
904
909
|
emit TierDelegateAttestationsChanged(_to, _tierId, _oldValue, _newValue, msg.sender);
|
|
905
910
|
}
|
|
906
911
|
}
|
|
@@ -912,8 +917,9 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
|
|
|
912
917
|
if (context.amount.currency != pricingCurrency) revert DefifaHook_WrongCurrency();
|
|
913
918
|
|
|
914
919
|
// Resolve the metadata.
|
|
915
|
-
(bool found, bytes memory metadata) =
|
|
916
|
-
JBMetadataResolver.
|
|
920
|
+
(bool found, bytes memory metadata) = JBMetadataResolver.getDataFor({
|
|
921
|
+
id: JBMetadataResolver.getId({purpose: "pay", target: codeOrigin}), metadata: context.payerMetadata
|
|
922
|
+
});
|
|
917
923
|
|
|
918
924
|
if (!found) revert DefifaHook_NothingToMint();
|
|
919
925
|
|
|
@@ -987,13 +993,13 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
|
|
|
987
993
|
// If minting, add to the total tier checkpoints.
|
|
988
994
|
if (_from == address(0)) {
|
|
989
995
|
// slither-disable-next-line unused-return
|
|
990
|
-
_totalTierCheckpoints[_tierId].push(uint48(block.timestamp), _current + uint208(_amount));
|
|
996
|
+
_totalTierCheckpoints[_tierId].push({key: uint48(block.timestamp), value: _current + uint208(_amount)});
|
|
991
997
|
}
|
|
992
998
|
|
|
993
999
|
// If burning, subtract from the total tier checkpoints.
|
|
994
1000
|
if (_to == address(0)) {
|
|
995
1001
|
// slither-disable-next-line unused-return
|
|
996
|
-
_totalTierCheckpoints[_tierId].push(uint48(block.timestamp), _current - uint208(_amount));
|
|
1002
|
+
_totalTierCheckpoints[_tierId].push({key: uint48(block.timestamp), value: _current - uint208(_amount)});
|
|
997
1003
|
}
|
|
998
1004
|
}
|
|
999
1005
|
|
|
@@ -160,8 +160,9 @@ contract DefifaTokenUriResolver is IDefifaTokenUriResolver, IJB721TokenUriResolv
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
if (_gamePhase == DefifaGamePhase.SCORING || _gamePhase == DefifaGamePhase.COMPLETE) {
|
|
163
|
-
uint256 _potPortion =
|
|
164
|
-
|
|
163
|
+
uint256 _potPortion = mulDiv({
|
|
164
|
+
x: _gamePot, y: _hook.cashOutWeightOf(_tokenId), denominator: _hook.TOTAL_CASHOUT_WEIGHT()
|
|
165
|
+
});
|
|
165
166
|
_valueText = !_hook.cashOutWeightIsSet()
|
|
166
167
|
? "Awaiting scorecard..."
|
|
167
168
|
: _formatBalance({
|
|
@@ -248,7 +248,9 @@ library DefifaHookLib {
|
|
|
248
248
|
cashOutCount = cumulativeMintPrice;
|
|
249
249
|
} else {
|
|
250
250
|
// If the game is in its scoring or complete phase, reclaim amount is based on the tier weights.
|
|
251
|
-
cashOutCount = mulDiv(
|
|
251
|
+
cashOutCount = mulDiv({
|
|
252
|
+
x: surplusValue + _amountRedeemed, y: cumulativeCashOutWeight, denominator: TOTAL_CASHOUT_WEIGHT
|
|
253
|
+
});
|
|
252
254
|
}
|
|
253
255
|
}
|
|
254
256
|
|
|
@@ -348,8 +350,8 @@ library DefifaHookLib {
|
|
|
348
350
|
uint256 defifaAmount = _defifaToken.balanceOf(address(this)) * shareToBeneficiary / outOfTotal;
|
|
349
351
|
|
|
350
352
|
// If there is an amount we should send, send it.
|
|
351
|
-
if (defifaAmount != 0) _defifaToken.safeTransfer(_beneficiary, defifaAmount);
|
|
352
|
-
if (baseProtocolAmount != 0) _baseProtocolToken.safeTransfer(_beneficiary, baseProtocolAmount);
|
|
353
|
+
if (defifaAmount != 0) _defifaToken.safeTransfer({to: _beneficiary, value: defifaAmount});
|
|
354
|
+
if (baseProtocolAmount != 0) _baseProtocolToken.safeTransfer({to: _beneficiary, value: baseProtocolAmount});
|
|
353
355
|
|
|
354
356
|
emit ClaimedTokens(_beneficiary, defifaAmount, baseProtocolAmount, msg.sender);
|
|
355
357
|
|