Skip to content

Commit d99e526

Browse files
committed
refactor: use forge lint over solhint and adjust code accordingly
1 parent 0c8d625 commit d99e526

34 files changed

+165
-1525
lines changed

pnpm-lock.yaml

Lines changed: 0 additions & 44 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

status-network-contracts/.gas-report

Lines changed: 4 additions & 758 deletions
Large diffs are not rendered by default.

status-network-contracts/.gas-snapshot

Lines changed: 1 addition & 349 deletions
Large diffs are not rendered by default.

status-network-contracts/.solhint.json

Lines changed: 0 additions & 13 deletions
This file was deleted.

status-network-contracts/foundry.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@
4242
tab_width = 4
4343
wrap_comments = true
4444

45-
[profile.lint]
45+
[lint]
4646
lint_on_build = false # Since we are using our own linting solution, we can disable built in one
47+
exclude_lints = ["mixed-case-variable", "mixed-case-function"]
48+
ignore = ["src/utils/ERC20VotesUpgradeable.sol"]
4749

4850
[rpc_endpoints]
4951
arbitrum = "https://arbitrum-mainnet.infura.io/v3/${API_KEY_INFURA}"

status-network-contracts/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
},
88
"devDependencies": {
99
"prettier": "^3.0.0",
10-
"solhint-community": "^3.6.0",
1110
"commit-and-tag-version": "^12.2.0"
1211
},
1312
"keywords": [
@@ -29,7 +28,7 @@
2928
"verify:mp_less_equal_max_mp": "certoraRun certora/confs/MPLessEqualMaxMP.conf",
3029
"verify:emergency_mode": "certoraRun certora/confs/EmergencyMode.conf",
3130
"verify:karma": "certoraRun certora/confs/Karma.conf",
32-
"lint:sol": "forge fmt --check && pnpm solhint {script,src,test,certora}/**/*.sol",
31+
"lint:sol": "forge fmt --check && forge lint",
3332
"prettier:check": "prettier --check **/*.{json,md,yml} --ignore-path=.prettierignore",
3433
"prettier:write": "prettier --write **/*.{json,md,yml} --ignore-path=.prettierignore",
3534
"gas-report": "forge snapshot --gas-report 2>&1 | (tee /dev/tty | awk '/Suite result:/ {found=1; buffer=\"\"; next} found && !/Ran/ {buffer=buffer $0 ORS} /Ran/ {found=0} END {printf \"%s\", buffer}' > .gas-report)",

status-network-contracts/script/DeployKarmaNFT.s.sol

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import { BaseScript } from "./Base.s.sol";
55
import { DeploymentConfig } from "./DeploymentConfig.s.sol";
66

77
import { KarmaNFT } from "../src/KarmaNFT.sol";
8-
import { NFTMetadataGeneratorSVG } from "../src/nft-metadata-generators/NFTMetadataGeneratorSVG.sol";
9-
import { INFTMetadataGenerator } from "../src/interfaces/INFTMetadataGenerator.sol";
108

119
/**
1210
* @dev Script for deploying KarmaNFT contract and its dependencies.
@@ -34,13 +32,7 @@ contract DeployKarmaNFTScript is BaseScript {
3432
* @return karmaNFT The deployed KarmaNFT contract instance.
3533
* @return deploymentConfig The DeploymentConfig instance for the current network.
3634
*/
37-
function runForTest(
38-
address metadataGenerator,
39-
address karmaAddress
40-
)
41-
public
42-
returns (KarmaNFT, DeploymentConfig)
43-
{
35+
function runForTest(address metadataGenerator, address karmaAddress) public returns (KarmaNFT, DeploymentConfig) {
4436
DeploymentConfig deploymentConfig = new DeploymentConfig(broadcaster);
4537
KarmaNFT karmaNFT = deploy(broadcaster, metadataGenerator, karmaAddress);
4638
return (karmaNFT, deploymentConfig);

status-network-contracts/script/DeployStakeManager.s.sol

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity ^0.8.26;
33

4-
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
54
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
6-
import { Clones } from "@openzeppelin/contracts/proxy/Clones.sol";
75

86
import { BaseScript } from "./Base.s.sol";
97
import { DeploymentConfig } from "./DeploymentConfig.s.sol";
108

119
import { StakeManager } from "../src/StakeManager.sol";
12-
import { StakeVault } from "../src/StakeVault.sol";
13-
import { VaultFactory } from "../src/VaultFactory.sol";
1410

1511
/**
1612
* @dev This script deploys the StakeManager contract as an upgradeable proxy using a Transparent Proxy pattern.

status-network-contracts/src/Karma.sol

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ pragma solidity 0.8.26;
44
import { AccessControlUpgradeable } from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
55
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
66
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
7-
import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
87
import { ERC20VotesUpgradeable } from "./utils/ERC20VotesUpgradeable.sol";
98
import { IRewardDistributor } from "./interfaces/IRewardDistributor.sol";
109
import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
@@ -88,17 +87,13 @@ contract Karma is Initializable, ERC20VotesUpgradeable, UUPSUpgradeable, AccessC
8887

8988
/// @notice Modifier to check if sender is admin or operator
9089
modifier onlyAdminOrOperator() {
91-
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender) && !hasRole(OPERATOR_ROLE, msg.sender)) {
92-
revert Karma__Unauthorized();
93-
}
90+
_onlyAdminOrOperator(msg.sender);
9491
_;
9592
}
9693

9794
/// @notice Modifier to check if sender has slasher role
9895
modifier onlySlasher() {
99-
if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender) && !hasRole(SLASHER_ROLE, msg.sender)) {
100-
revert Karma__Unauthorized();
101-
}
96+
_onlySlasher(msg.sender);
10297
_;
10398
}
10499

@@ -397,6 +392,18 @@ contract Karma is Initializable, ERC20VotesUpgradeable, UUPSUpgradeable, AccessC
397392
return (super.balanceOf(account) + externalBalance);
398393
}
399394

395+
function _onlyAdminOrOperator(address sender) internal view {
396+
if (!hasRole(DEFAULT_ADMIN_ROLE, sender) && !hasRole(OPERATOR_ROLE, sender)) {
397+
revert Karma__Unauthorized();
398+
}
399+
}
400+
401+
function _onlySlasher(address sender) internal view {
402+
if (!hasRole(DEFAULT_ADMIN_ROLE, sender) && !hasRole(SLASHER_ROLE, sender)) {
403+
revert Karma__Unauthorized();
404+
}
405+
}
406+
400407
/*//////////////////////////////////////////////////////////////////////////
401408
VIEW FUNCTIONS
402409
//////////////////////////////////////////////////////////////////////////*/

status-network-contracts/src/KarmaAirdrop.sol

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,39 +33,41 @@ contract KarmaAirdrop is Ownable2Step, Pausable {
3333
event MerkleRootSet(bytes32 merkleRoot);
3434

3535
/// @notice The address of the Karma token contract
36-
address public immutable token;
36+
address public immutable TOKEN;
3737
/// @notice Whether the merkle root can be updated more than once
38-
bool public immutable allowMerkleRootUpdate;
38+
bool public immutable ALLOW_MERKLE_ROOT_UPDATE;
3939
/// @notice The default delegatee address for new claimers
40-
address public immutable defaultDelegatee;
40+
address public immutable DEFAULT_DELEGATEE;
4141
/// @notice The Merkle root of the airdrop
4242
bytes32 public merkleRoot;
4343
/// @notice Current epoch - incremented with each merkle root update
4444
uint256 public epoch;
4545
/// @notice A bitmap to track claimed indices per epoch
4646
mapping(uint256 => mapping(uint256 => uint256)) private claimedBitMap;
47+
/// @notice Base value for creating bitmap masks
48+
uint256 private constant BITMAP_MASK_BASE = 1;
4749

4850
constructor(address _token, address _owner, bool _allowMerkleRootUpdate, address _defaultDelegatee) {
49-
token = _token;
50-
allowMerkleRootUpdate = _allowMerkleRootUpdate;
51-
defaultDelegatee = _defaultDelegatee;
51+
TOKEN = _token;
52+
ALLOW_MERKLE_ROOT_UPDATE = _allowMerkleRootUpdate;
53+
DEFAULT_DELEGATEE = _defaultDelegatee;
5254
_transferOwnership(_owner);
5355
}
5456

5557
/**
5658
* @notice Sets the Merkle root for the airdrop. Can only be called by the owner.
57-
* If allowMerkleRootUpdate is false, can only be called once.
59+
* If ALLOW_MERKLE_ROOT_UPDATE;is false, can only be called once.
5860
* When updating an existing merkle root, the contract must be paused to prevent front-running.
5961
* When the merkle root is updated, the epoch is incremented, creating a new bitmap.
6062
* @param _merkleRoot The Merkle root to set
6163
*/
6264
function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
63-
if (!allowMerkleRootUpdate && merkleRoot != bytes32(0)) {
65+
if (!ALLOW_MERKLE_ROOT_UPDATE && merkleRoot != bytes32(0)) {
6466
revert KarmaAirdrop__MerkleRootAlreadySet();
6567
}
6668

6769
// When updating an existing merkle root (not the first time), contract must be paused
68-
if (allowMerkleRootUpdate && merkleRoot != bytes32(0) && !paused()) {
70+
if (ALLOW_MERKLE_ROOT_UPDATE && merkleRoot != bytes32(0) && !paused()) {
6971
revert KarmaAirdrop__MustBePausedToUpdate();
7072
}
7173

@@ -87,14 +89,15 @@ contract KarmaAirdrop is Ownable2Step, Pausable {
8789
uint256 claimedWordIndex = index / 256;
8890
uint256 claimedBitIndex = index % 256;
8991
uint256 claimedWord = claimedBitMap[epoch][claimedWordIndex];
90-
uint256 mask = (1 << claimedBitIndex);
92+
uint256 mask = (BITMAP_MASK_BASE << claimedBitIndex);
9193
return claimedWord & mask == mask;
9294
}
9395

9496
function _setClaimed(uint256 index) private {
9597
uint256 claimedWordIndex = index / 256;
9698
uint256 claimedBitIndex = index % 256;
97-
claimedBitMap[epoch][claimedWordIndex] = claimedBitMap[epoch][claimedWordIndex] | (1 << claimedBitIndex);
99+
claimedBitMap[epoch][claimedWordIndex] =
100+
claimedBitMap[epoch][claimedWordIndex] | (BITMAP_MASK_BASE << claimedBitIndex);
98101
}
99102

100103
/**
@@ -130,20 +133,21 @@ contract KarmaAirdrop is Ownable2Step, Pausable {
130133
}
131134

132135
// Verify the merkle proof.
136+
/// forge-lint: disable-next-line(asm-keccak256)
133137
bytes32 node = keccak256(abi.encodePacked(index, account, amount));
134138
if (!MerkleProof.verify(merkleProof, merkleRoot, node)) {
135139
revert KarmaAirdrop__InvalidProof();
136140
}
137141

138142
// Mark it claimed and send the token.
139143
_setClaimed(index);
140-
if (!IERC20(token).transfer(account, amount)) {
144+
if (!IERC20(TOKEN).transfer(account, amount)) {
141145
revert KarmaAirdrop__TransferFailed();
142146
}
143147

144148
// If the account has no karma balance before this claim, delegate to the default delegatee
145-
if (IERC20(token).balanceOf(account) == amount) {
146-
IVotes(token).delegateBySig(defaultDelegatee, nonce, expiry, v, r, s);
149+
if (IERC20(TOKEN).balanceOf(account) == amount) {
150+
IVotes(TOKEN).delegateBySig(DEFAULT_DELEGATEE, nonce, expiry, v, r, s);
147151
}
148152

149153
emit Claimed(index, account, amount);

0 commit comments

Comments
 (0)