Repository navigation
Conversation
…and reentrancy
### Description
This PR hardens the core governance smart contracts (`NetworkStateAgreement` and `NetworkStateInitiatives`) within the `ai-cns` repository, addressing critical authorization, validation, and execution vulnerabilities.
**Vulnerabilities & Security Defects Remediated:**
* **Cryptographic Authorization & Replay (`NetworkStateAgreement.sol`):** `signAgreement` now correctly hashes the contract address, chain ID, caller, profile, agent nature, and constitution, recovering the signer via OpenZeppelin's `ECDSA`. This strictly requires `recoveredSigner == msg.sender`, preventing attackers from submitting arbitrary signature bytes.
* **Checks-Effects-Interactions (`NetworkStateAgreement.sol`):** Agreement state is committed only after the treasury transfer and cross-contract credit allocation succeed, mitigating reentrancy risks alongside the `nonReentrant` modifier.
* **Unauthorized Credit Issuance & Regeneration (`NetworkStateInitiatives.sol`):** `updateUserCredits` is now restricted by the `onlyCreditManager` modifier. The implicit credit refill mechanism was removed from the voting path, and exhausted credits can no longer be regenerated via repeated calls.
* **Voting Without Agreement Membership (`NetworkStateInitiatives.sol`):** Voting paths (`upvote` and `downvote`) now strictly invoke `_requireAgreement()`, meaning unverified users can no longer mutate vote state.
* **Initiator Spoofing (`NetworkStateInitiatives.sol`):** `createInitiatives` now strictly requires `_ideator == msg.sender`, keeping proposal ownership aligned with the transaction signer.
* **Silent Acceptance of Unknown IDs (`NetworkStateInitiatives.sol`):** Funding, voting, status, and team-management paths now use `_requireInitiative()`, which correctly reverts if an initiative ID is not found, preventing silent state corruption or trapped ether.
* **Status and Team Authorization Drift (`NetworkStateInitiatives.sol`):** Initiative status updates are restricted strictly to `onlyOwner`. Team membership changes now explicitly check that the caller is the owner, ideator, or instigator.
* **Unsafe Ether Transfer (`NetworkStateInitiatives.sol`):** Replaced fixed-gas `transfer` calls with checked low-level `call{value: ...}("")` under `nonReentrant` guards for safe treasury forwarding and withdrawals.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 54a9e25. Configure here.
Fix formatting by adding a newline at the end of the file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Description
This PR hardens the core governance smart contracts (
NetworkStateAgreementandNetworkStateInitiatives) within theai-cnsrepository, addressing critical authorization, validation, and execution vulnerabilities.Vulnerabilities & Security Defects Remediated:
NetworkStateAgreement.sol):signAgreementnow correctly hashes the contract address, chain ID, caller, profile, agent nature, and constitution, recovering the signer via OpenZeppelin'sECDSA. This strictly requiresrecoveredSigner == msg.sender, preventing attackers from submitting arbitrary signature bytes.NetworkStateAgreement.sol): Agreement state is committed only after the treasury transfer and cross-contract credit allocation succeed, mitigating reentrancy risks alongside thenonReentrantmodifier.NetworkStateInitiatives.sol):updateUserCreditsis now restricted by theonlyCreditManagermodifier. The implicit credit refill mechanism was removed from the voting path, and exhausted credits can no longer be regenerated via repeated calls.NetworkStateInitiatives.sol): Voting paths (upvoteanddownvote) now strictly invoke_requireAgreement(), meaning unverified users can no longer mutate vote state.NetworkStateInitiatives.sol):createInitiativesnow strictly requires_ideator == msg.sender, keeping proposal ownership aligned with the transaction signer.NetworkStateInitiatives.sol): Funding, voting, status, and team-management paths now use_requireInitiative(), which correctly reverts if an initiative ID is not found, preventing silent state corruption or trapped ether.NetworkStateInitiatives.sol): Initiative status updates are restricted strictly toonlyOwner. Team membership changes now explicitly check that the caller is the owner, ideator, or instigator.NetworkStateInitiatives.sol): Replaced fixed-gastransfercalls with checked low-levelcall{value: ...}("")undernonReentrantguards for safe treasury forwarding and withdrawals.Note
High Risk
Touches core on-chain auth, credit issuance, voting, and ETH transfers. Incorrect signature, instigator, or reentrancy behavior could lock funds or let unauthorized users vote.
Overview
Hardens the two governance contracts so agreement signing, credits, voting, and funding can no longer be spoofed or silently fail.
NetworkStateAgreementnow verifies ECDSA signatures over contract, chain, caller, profile, agent, and constitution hash. Constructor rejects zero addresses. Ether is forwarded and credits are granted before recordinghasAgreed. Adds a publichasAgreedview for the initiatives contract.NetworkStateInitiativeswires an agreement contract (setAgreementContract) and requires a signed agreement before upvote/downvote. Credits can only be set by owner or the agreement contract; the old auto-refill on vote is gone. Creating an initiative requires_ideator == msg.sender. Unknown initiative IDs revert. Status updates are owner-only. Team edits are limited to owner/ideator/instigator. Instigator is assigned to the ideator after a +5 upvote margin instead of during status change.Withdrawals use checked
callplusnonReentrant. Initiative IDs include a per-sender nonce instead of block entropy.Reviewed by Cursor Bugbot for commit 34fb235. Bugbot is set up for automated code reviews on this repo. Configure here.