> For the complete documentation index, see [llms.txt](https://docs.zestprotocol.com/start/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zestprotocol.com/start/stacks-market-smart-contracts/v2-contracts/dao-contracts/dao-multisig.md).

# DAO Multisig

Purpose: Multisig governance for DAO proposal management. Manages signers, approval thresholds, and proposal execution with timelocks.

## List of Core Functions

Signer Management

* init — Initialize DAO with signers and threshold
* add-signer — Add new signer
* remove-signer — Remove existing signer
* set-threshold — Update approval threshold
* get-threshold — Get current approval threshold
* get-signer-count — Get total number of signers
* is-signer — Check if address is authorized signer

Proposal Management

* propose — Create new proposal
* approve — Approve proposal
* execute — Execute approved proposal
* get-nonce — Get proposal counter
* get-proposal — Get proposal details
* get-approval-count — Count approvals for proposal
* has-approved — Check if signer approved proposal
* set-default-expiry-duration — Set proposal expiry time

Implementation Updates

* schedule-impl-update — Schedule implementation upgrade (7-day timelock)
* execute-impl-update — Execute scheduled implementation upgrade
* cancel-impl-update — Cancel pending implementation upgrade
* get-pending-impl-update — Get scheduled implementation update details

***

## Function Reference

### init

Initialize DAO with signers and approval threshold. One-time setup by deployer.

Parameters:

| Parameter     | Type                | Description                                |
| ------------- | ------------------- | ------------------------------------------ |
| signer-list   | (list 20 principal) | List of initial signer addresses           |
| new-threshold | uint                | Number of approvals required for execution |

Returns: `(response bool uint)` — Success or error

Authorization: Deployer only, one-time

***

### add-signer

Add new signer to DAO. Maximum 20 signers allowed.

Parameters:

| Parameter | Type      | Description                        |
| --------- | --------- | ---------------------------------- |
| addr      | principal | Address to grant signer privileges |

Returns: `(response bool uint)` — Success or error

Authorization: DAO executor only (via approved proposal)

***

### remove-signer

Remove signer from DAO. Cannot remove if it would make threshold unreachable.

Parameters:

| Parameter | Type      | Description              |
| --------- | --------- | ------------------------ |
| addr      | principal | Signer address to remove |

Returns: `(response bool uint)` — Success or error

Authorization: DAO executor only (via approved proposal)

Constraints: Remaining signers must meet or exceed threshold

***

### set-threshold

Update approval threshold required for proposal execution.

Parameters:

| Parameter     | Type | Description                                                     |
| ------------- | ---- | --------------------------------------------------------------- |
| new-threshold | uint | New approval count requirement (must be > 0 and ≤ signer count) |

Returns: `(response bool uint)` — Success or error

Authorization: DAO executor only (via approved proposal)

***

### get-threshold

Get current approval threshold.

Parameters: none

Returns: `uint` — Current approval threshold

***

### get-signer-count

Get total number of authorized signers.

Parameters: none

Returns: `uint` — Total signer count

***

### get-nonce

Get current proposal counter (next proposal ID).

Parameters: none

Returns: `uint` — Next proposal ID

***

### is-signer

Check if address is authorized signer.

Parameters:

| Parameter | Type      | Description      |
| --------- | --------- | ---------------- |
| addr      | principal | Address to check |

Returns: `bool` — True if authorized signer, false otherwise

***

### propose

Create new proposal. Returns proposal ID.

Parameters:

| Parameter | Type      | Description                                                           |
| --------- | --------- | --------------------------------------------------------------------- |
| script    | principal | Proposal contract address (must implement proposal-script trait)      |
| urgent    | bool      | If true, bypasses 1-day timelock (still requires threshold approvals) |

Returns: `(response uint uint)` — Proposal ID or error

Authorization: Signer only

Note: Proposer's approval automatically counted

***

### approve

Approve proposal. Cannot approve own proposal twice or after execution.

Parameters:

| Parameter | Type | Description            |
| --------- | ---- | ---------------------- |
| id        | uint | Proposal ID to approve |

Returns: `(response bool uint)` — Success or error

Authorization: Signer only

Constraints: Proposal must not be expired or already executed

***

### execute

Execute proposal if threshold met and timelock passed.

Parameters:

| Parameter | Type | Description                                              |
| --------- | ---- | -------------------------------------------------------- |
| id        | uint | Proposal ID to execute                                   |
| script    |      | Proposal contract (must match proposal's script address) |

Returns: `(response bool uint)` — Success or error

Authorization: Signer only

Conditions:

* Approval count ≥ threshold
* Timelock passed (1 day) OR proposal marked urgent
* Not expired (default 30 days)
* Not already executed

***

### get-proposal

Get proposal details by ID.

Parameters:

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| id        | uint | Proposal ID |

Returns: `(optional {...})` — Proposal data or none

Proposal fields:

* script: principal — Proposal contract address
* approvals: (list 20 principal) — List of signers who approved
* executed: bool — Whether proposal was executed
* created-at: uint — Creation timestamp
* urgent: bool — Whether urgent (skips timelock)
* expires-at: uint — Expiration timestamp

***

### get-approval-count

Count approvals for proposal.

Parameters:

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| id        | uint | Proposal ID |

Returns: `(optional uint)` — Approval count or none if proposal doesn't exist

***

### has-approved

Check if signer approved proposal.

Parameters:

| Parameter | Type      | Description             |
| --------- | --------- | ----------------------- |
| signer    | principal | Signer address to check |
| id        | uint      | Proposal ID             |

Returns: `bool` — True if signer approved, false otherwise

***

### set-default-expiry-duration

Set default expiry duration for new proposals.

Parameters:

| Parameter | Type | Description                                  |
| --------- | ---- | -------------------------------------------- |
| duration  | uint | Expiry duration in seconds (must be ≥ 1 day) |

Returns: `(response bool uint)` — Success or error

Authorization: DAO executor only (via approved proposal)

Default: 30 days (2592000 seconds)

***

### schedule-impl-update

Schedule implementation upgrade with 7-day timelock. Prevents other impl updates until executed or cancelled.

Parameters:

| Parameter | Type      | Description                         |
| --------- | --------- | ----------------------------------- |
| new-impl  | principal | New implementation contract address |

Returns: `(response bool uint)` — Success or error

Authorization: DAO executor only (via approved proposal)

Note: Starts 7-day timelock before execution allowed

***

### execute-impl-update

Execute scheduled implementation upgrade after 7-day timelock.

Parameters: none

Returns: `(response bool uint)` — Success or error

Authorization: DAO executor only (via second approved proposal)

Constraints: Must wait 7 days after scheduling

***

### cancel-impl-update

Cancel pending implementation upgrade.

Parameters: none

Returns: `(response bool uint)` — Success or error

Authorization: DAO executor only (via approved proposal)

***

### get-pending-impl-update

Get scheduled implementation update details.

Parameters: none

Returns: `(optional {...})` — Update details or none

Fields:

*
