Proposing Initiatives
Function Signatures
Initiatives can include up to five optional attachments. Supply metadata via the
_attachmentsarray or pass an empty array when no supporting materials are needed.
Basic Proposal
function proposeInitiative(
Metadata calldata _metadata
) external returns (uint256 initiativeId)Proposal with Lock
function proposeInitiativeWithLock(
Metadata calldata _metadata,
uint256 _amount,
uint256 _lockDuration
) external returns (uint256 initiativeId, uint256 tokenId)Parameters
| Parameter | Type | Description |
|---|---|---|
_metadata | Metadata | Initiative metadata (title, body, attachments). Title must be non-empty; attachments max 5 with non-empty URIs |
_amount | uint256 | Amount of tokens to lock (in wei, e.g., 100000 * 1e18) |
_lockDuration | uint256 | Duration to lock tokens, measured in intervals (must be > 0 and ≤ maxLockIntervals) |
Metadata Struct
struct Metadata {
string title;
string body;
Attachment[] attachments;
}Title must be non-empty; body may be empty. Attachments are optional, capped at 5, and must have non-empty URIs.
Attachment Struct
struct Attachment {
string uri;
string mimeType;
string description;
}- Maximum of 5 attachments per initiative
urimust be provided for each attachment;mimeTypeanddescriptionare optional helpers for clients
Returns
initiativeId- ID of the newly created initiativetokenId- ERC721 NFT representing the lock position (only forproposeInitiativeWithLock)
Metadata storage: metadata is emitted in InitiativeProposed and not stored on-chain.
Initiative Data Structure
struct Initiative {
InitiativeState state; // Current state (Proposed, Accepted, Cancelled, Expired)
address proposer; // Proposer address
uint256 timestamp; // Creation timestamp
uint256 lastActivity; // Last activity timestamp
uint256 acceptanceTimestamp; // When accepted (0 if not yet accepted)
}Initiative States
enum InitiativeState {
Proposed, // Initial state, can receive support
Accepted, // Board owner accepted the initiative
Cancelled, // Reserved for future use
Expired // No activity for > inactivityTimeout
}Proposer Requirements
struct ParticipantRequirements {
address token;
uint256 minBalance;
uint256 minHoldingDuration;
uint256 minLockAmount;
}tokenis the ERC20/IVotes token used for eligibility checks (can differ from the underlying lock token).minBalance == 0andminHoldingDuration == 0: no balance requirement.minBalance > 0andminHoldingDuration == 0: current balance check only.minBalance > 0andminHoldingDuration > 0: historical balance check (requiresIVotesontoken).minLockAmountenforces a minimum lock amount forproposeInitiativeWithLock.
tokencannot beaddress(0).minHoldingDuration > 0requiresminBalance > 0and an IVotes-compatible token.minLockAmountmust be ≤minBalance.
Events Emitted
InitiativeProposed
event InitiativeProposed(
uint256 indexed initiativeId,
address indexed proposer,
Metadata metadata
)InitiativeSupported
Emitted when using proposeInitiativeWithLock:
event InitiativeSupported(
uint256 indexed initiativeId,
address indexed supporter,
uint256 tokenAmount,
uint256 lockDuration,
uint256 tokenId // ERC721 NFT ID
)Validation & Errors
| Error | Cause | Solution |
|---|---|---|
Signals_EmptyTitleOrBody | Title is empty | Provide a non-empty title |
Signals_IncorrectBoardState | Board not open | Wait for board to open |
Signals_InsufficientTokens | Balance < required amount | Acquire more tokens |
Signals_InsufficientTokenDuration | Haven't held tokens long enough | Wait or use different account |
Signals_InsufficientLockAmount | Lock amount below minLockAmount | Increase lock amount or update requirements |
Signals_TokenHasNoCheckpointSupport | Token doesn't support IVotes | Board misconfigured |
Signals_InvalidArguments | Invalid lock duration or attachment URI | Use valid duration and attachment data |
Signals_TokenTransferFailed | Token transfer reverted | Check approval and balance |
Signals_AttachmentLimitExceeded | More than 5 attachments provided | Trim the attachment list before submitting |
Helper Functions
// Check if address can propose with a given lock amount
function accountCanPropose(address account, uint256 lockAmount) external view returns (bool)
// Get current proposer requirements
function getProposerRequirements() external view returns (ParticipantRequirements memory)
// Get board configuration
function getBoardConfig() external view returns (BoardConfig memory)Token approval: proposeInitiativeWithLock requires the caller to approve the Signals contract for _amount on the underlying ERC20.
