# PIP-40: Refill the V1 Privacy Rewards Reserve and Adjust Reward Emissions on Polygon
## Proposal summary
This proposal authorises the minting and release of an additional **4,000,000 $ZKP** to the **V1 ZkpReserveController** on Polygon and sets the V1 privacy reward emission rate to approximately **16,000 $ZKP per day**.
The objective is to restore V1 privacy reward distributions while aligning ongoing emissions more closely with the protocol’s current Total Value Locked (TVL) and usage.
- Mint **4,000,000 $ZKP** on Ethereum through a new vesting pool.
- Release the full allocation to the Ethereum DAO Multisig.
- Bridge the **4,000,000 $ZKP** to the V1 `ZkpReserveController` on Polygon.
- Set the reward drip rate to approximately **16,000 $ZKP per day**.
- Leave the `minRewardableAmount` unchanged at **20,000 $ZKP**.
- Execute the required Ethereum and cross-chain governance transactions following a successful Snapshot vote.
—
## Motivation
### 1. Restore V1 privacy rewards
- The V1 `ZkpReserveController` on Polygon has run out of $ZKP, preventing the PRP/ZKP reward pool from being refilled.
- V1 continues to support user activity and remains an active component of the Panther ecosystem.
- Without a new allocation, eligible users can no longer receive the intended privacy rewards.
- Replenishing the reserve restores uninterrupted reward distribution for eligible V1 activity.
### 2. Align emissions with current TVL
- The previous reward emission rate was established under different protocol and market conditions.
- Current emissions should more closely reflect the protocol’s present TVL and level of usage.
- Setting the drip rate to approximately **16,000 $ZKP per day** maintains meaningful user incentives while reducing the risk of distributing rewards faster than the current ecosystem can sustainably absorb.
- A more measured emission rate extends the lifetime of the new allocation and limits unnecessary increases in circulating supply.
### 3. Responsible reward management
- Combining the reserve refill and emission-rate adjustment in one proposal ensures that the additional allocation is released under an updated and more sustainable distribution schedule.
- The new **4,000,000 $ZKP** allocation would last approximately **250 days** at a constant emission rate of **16,000 $ZKP per day**, excluding any operational differences arising from block timing or reward conditions.
- The proposal does not alter the underlying reward mechanism or the minimum amount required for a refill.
- All minting, bridging, and parameter updates remain subject to community approval and DAO-controlled execution.
—
## Proposed changes
### 1. Create and release a 4,000,000 $ZKP vesting allocation
- Create Vesting Pool #24 containing **4,000,000 $ZKP**.
- Assign the Ethereum DAO Multisig as the pool wallet.
- Update the pool start time so the entire allocation becomes immediately releasable.
- Release the full **4,000,000 $ZKP** allocation to the Ethereum DAO Multisig.
### 2. Bridge the allocation to Polygon
- Approve the Polygon PoS ERC20 predicate to transfer the **4,000,000 $ZKP**.
- Bridge the full allocation from Ethereum to Polygon.
- Credit the Polygon representation of $ZKP directly to the V1 `ZkpReserveController`.
### 3. Set the V1 reward drip rate
- Set the `ZkpReserveController` reward rate to **0.277778 $ZKP per Polygon block**.
- This corresponds to approximately **16,000 $ZKP per day**, assuming a 1.5-second Polygon block time.
- Keep the `minRewardableAmount` unchanged at **20,000 $ZKP**.
- Execute the parameter update through cross-chain governance using `approveHash` and `execTransaction` on `ownerSafeDao`.
### 4. Governance execution
- Execute five direct Ethereum transactions covering vesting, release, approval, and bridging.
- Execute two Ethereum bridge-wrapper transactions carrying the Polygon governance actions.
- All seven transactions will be signed by the Ethereum DAO Multisig.
—
## Next steps
### Community feedback
Members are invited to review and comment on:
- Whether the proposed **4,000,000 $ZKP** allocation is appropriate.
- Whether approximately **16,000 $ZKP per day** appropriately balances user incentives with the protocol’s current TVL.
- Whether retaining the **20,000 $ZKP** minimum rewardable amount remains suitable.
- Whether the proposed execution sequence and cross-chain governance actions are acceptable.
### Voting
- **PIP-40** will be published on Snapshot for a **3-day** vote, with voting eligibility defined in **PIP-7**.
—
## Execution addresses
Panther / bridge contracts on Ethereum:
- DAO_Multisig@eth: 0x505796f5bc290269d2522cf19135ad7aa60dfd77
- FxRoot@eth: 0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2
- VestingPools@eth: 0xb476104aa9D1f30180a01987FB09b1e96dDCF14B
- ZKP@eth: 0x909E34d3f6124C324ac83DccA84b74398a6fa173
- ERC20Predicate@eth: 0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf
- RootChainManager@eth: 0xA0c68C638235ee32657e8f720a23ceC1bFc77C77
Panther contracts on Polygon:
- polygonMultisig (DAO Safe)@matic: 0x208Fb9169BBec5915722e0AfF8B0eeEdaBf8a6f0
- ownerSafeDao@matic: 0x026a024b13B4Ca23897ad578264C0ec543f904b9
- MaticBridgeModule@matic: 0x4A4FC40d2475f493EcA3Ec436b924237AA1b0a76
- ZkpReserveController@matic: 0xf86896a029f0bE45a950e6dff9DDbb39AE237723
## Code execution
### Transactions overview
The ZkpReserveController on Polygon has run out of ZKP, so the PRP/ZKP pool is no longer being refilled. This proposal: (1) creates Vesting Pool #24 containing 4,000,000 ZKP with the DAO Multisig as wallet; (2) moves its start into the past so the entire allocation is releasable; (3) releases (mints) the 4,000,000 ZKP to the DAO Multisig; (4–5) approves and bridges the 4,000,000 ZKP through the Polygon PoS bridge directly to the ZkpReserveController; and (6–7) updates the controller’s emission rate to 0.277778 ZKP per block, approximately 16,000 ZKP per day at Polygon’s assumed 1.5-second block time. The `minRewardableAmount` remains unchanged at 20,000 ZKP. The parameter update is executed through cross-chain governance using Mode C: `approveHash` followed by `execTransaction` on `ownerSafeDao`.
> **Execution deadline:** Transaction 1 must execute before **31 August 2026**, otherwise it will revert because the temporary pool start time would already be in the past. All seven transactions are signed by the Ethereum DAO Multisig.
1\. addVestingPools on VestingPools@eth // Add vesting pool #24: 4,000,000 ZKP, wallet = DAO Multisig, start 2026-08-31 (future), 1 vesting day
2\. updatePoolTime on VestingPools@eth // Move pool #24 start to 2026-07-01 (past) so the whole 4M allocation is releasable
3\. releaseTo on VestingPools@eth // Release (mint) 4,000,000 ZKP from pool #24 to the DAO Multisig
4\. approve on ZKP@eth // Approve the Polygon PoS ERC20 predicate to pull 4,000,000 ZKP
5\. depositFor on RootChainManager@eth // Bridge 4,000,000 ZKP to Polygon: pZKP is credited directly to the ZkpReserveController
6\. FxRoot@eth::sendMessageToChild(MaticBridgeModule, encodedPayload) // Approve updateParams hash — ZkpReserveController.updateParams(277778000000000000, 20000000000000000000000) (bridge nonce 59)
7\. FxRoot@eth::sendMessageToChild(MaticBridgeModule, encodedPayload) // Execute updateParams — ZkpReserveController.updateParams(277778000000000000, 20000000000000000000000) (bridge nonce 60)
### Batch #1 — Ethereum direct actions (5 transactions)
Tx #1: Add vesting pool #24: 4,000,000 ZKP, wallet = DAO Multisig, start 2026-08-31 (future), 1 vesting day, adjustable, not pre-minted
To:
0xb476104aa9D1f30180a01987FB09b1e96dDCF14B // VestingPools@eth
Value:
0
Data:
0xe11d1a98000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000505796f5bc290269d2522cf19135ad7aa60dfd77000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000006a94c4000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000003a352944000000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000000000
Method:
addVestingPools(address\[\],(bool,bool,uint32,uint16,uint48,uint48,uint96)\[\])
Tx #2: Move pool #24 start to 2026-07-01 (past) so the whole 4M allocation is releasable
To:
0xb476104aa9D1f30180a01987FB09b1e96dDCF14B // VestingPools@eth
Value:
0
Data:
0xdb66bbd10000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000006a4458800000000000000000000000000000000000000000000000000000000000000001
Method:
updatePoolTime(uint256,uint32,uint16)
Tx #3: Release (mint) 4,000,000 ZKP from pool #24 to the DAO Multisig
To:
0xb476104aa9D1f30180a01987FB09b1e96dDCF14B // VestingPools@eth
Value:
0
Data:
0x2a7d7bc50000000000000000000000000000000000000000000000000000000000000018000000000000000000000000505796f5bc290269d2522cf19135ad7aa60dfd77000000000000000000000000000000000000000000034f086f3b33b684000000
Method:
releaseTo(uint256,address,uint256)
Tx #4: Approve the Polygon PoS ERC20 predicate to pull 4,000,000 ZKP
To:
0x909E34d3f6124C324ac83DccA84b74398a6fa173 // ZKP@eth
Value:
0
Data:
0x095ea7b300000000000000000000000040ec5b33f54e0e8a33a975908c5ba1c14e5bbbdf000000000000000000000000000000000000000000034f086f3b33b684000000
Method:
approve(address,uint256)
Tx #5: Bridge 4,000,000 ZKP to Polygon: pZKP is credited directly to the ZkpReserveController
To:
0xA0c68C638235ee32657e8f720a23ceC1bFc77C77 // RootChainManager@eth
Value:
0
Data:
0xe3dec8fb000000000000000000000000f86896a029f0be45a950e6dff9ddbb39ae237723000000000000000000000000909e34d3f6124c324ac83dcca84b74398a6fa17300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000034f086f3b33b684000000
Method:
depositFor(address,address,bytes)
### Batch #2 — Polygon bridge wrappers (2 transactions, signed on Ethereum)
Tx #6: Approve updateParams hash — ZkpReserveController.updateParams(277778000000000000, 20000000000000000000000)
To:
0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2 // FxRoot@eth
Value:
0
Data:
0xb47204770000000000000000000000004a4fc40d2475f493eca3ec436b924237aa1b0a7600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000026a024b13b4ca23897ad578264c0ec543f904b9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000024d4d9bdcdd6494bf8ca7f600df08a9b447a4d711052d7cfe63a11eb8372aa670188b2795200000000000000000000000000000000000000000000000000000000
Method:
sendMessageToChild(address,bytes)
Inner (Polygon-side):
target: 0x026a024b13B4Ca23897ad578264C0ec543f904b9 // ownerSafeDao
method: approveHash(bytes32)
bridge nonce: 59
Tx #7: Execute updateParams — ZkpReserveController.updateParams(277778000000000000, 20000000000000000000000)
To:
0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2 // FxRoot@eth
Value:
0
Data:
0xb47204770000000000000000000000004a4fc40d2475f493eca3ec436b924237aa1b0a7600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000320000000000000000000000000026a024b13b4ca23897ad578264c0ec543f904b9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000002446a761202000000000000000000000000f86896a029f0be45a950e6dff9ddbb39ae2377230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000044b649d12500000000000000000000000000000000000000000000000003dadd9e886b200000000000000000000000000000000000000000000000043c33c1937564800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041000000000000000000000000208fb9169bbec5915722e0aff8b0eeedabf8a6f00000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Method:
sendMessageToChild(address,bytes)
Inner (Polygon-side):
target: 0x026a024b13B4Ca23897ad578264C0ec543f904b9 // ownerSafeDao
method: execTransaction(...) -> updateParams(uint256,uint256)
bridge nonce: 60
### Batch #1 — JSON for Gnosis Safe Transaction Builder
\[
{
"to": "0xb476104aa9D1f30180a01987FB09b1e96dDCF14B",
"operation": "0",
"value": "0.0",
"data": "0xe11d1a98000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000505796f5bc290269d2522cf19135ad7aa60dfd77000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000006a94c4000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000003a352944000000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000000000000000",
},
{
"to": "0xb476104aa9D1f30180a01987FB09b1e96dDCF14B",
"operation": "0",
"value": "0.0",
"data": "0xdb66bbd10000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000006a4458800000000000000000000000000000000000000000000000000000000000000001",
"method": "updatePoolTime(uint256,uint32,uint16)",
"params": \["24","1782864000","1"\]
},
{
"to": "0xb476104aa9D1f30180a01987FB09b1e96dDCF14B",
"operation": "0",
"value": "0.0",
"data": "0x2a7d7bc50000000000000000000000000000000000000000000000000000000000000018000000000000000000000000505796f5bc290269d2522cf19135ad7aa60dfd77000000000000000000000000000000000000000000034f086f3b33b684000000",
"method": "releaseTo(uint256,address,uint256)",
"params": \["24","0x505796f5bc290269d2522cf19135ad7aa60dfd77","4000000000000000000000000"\]
},
{
"to": "0x909E34d3f6124C324ac83DccA84b74398a6fa173",
"operation": "0",
"value": "0.0",
"data": "0x095ea7b300000000000000000000000040ec5b33f54e0e8a33a975908c5ba1c14e5bbbdf000000000000000000000000000000000000000000034f086f3b33b684000000",
"method": "approve(address,uint256)",
"params": \["0x40ec5B33f54e0E8A33A975908C5BA1c14e5BbbDf","4000000000000000000000000"\]
},
{
"to": "0xA0c68C638235ee32657e8f720a23ceC1bFc77C77",
"operation": "0",
"value": "0.0",
"data": "0xe3dec8fb000000000000000000000000f86896a029f0be45a950e6dff9ddbb39ae237723000000000000000000000000909e34d3f6124c324ac83dcca84b74398a6fa17300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000034f086f3b33b684000000",
"method": "depositFor(address,address,bytes)",
"params": \["0xf86896a029f0bE45a950e6dff9DDbb39AE237723","0x909E34d3f6124C324ac83DccA84b74398a6fa173","0x000000000000000000000000000000000000000000034f086f3b33b684000000"\]
}
\]
### Batch #2 — JSON for Gnosis Safe Transaction Builder
\[
{
"to": "0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2",
"operation": "0",
"value": "0.0",
"data": "0xb47204770000000000000000000000004a4fc40d2475f493eca3ec436b924237aa1b0a7600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000026a024b13b4ca23897ad578264c0ec543f904b9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000024d4d9bdcdd6494bf8ca7f600df08a9b447a4d711052d7cfe63a11eb8372aa670188b2795200000000000000000000000000000000000000000000000000000000",
"method": "sendMessageToChild(address,bytes)",
"params": \[
"0x4A4FC40d2475f493EcA3Ec436b924237AA1b0a76",
"0x000000000000000000000000026a024b13b4ca23897ad578264c0ec543f904b9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000024d4d9bdcdd6494bf8ca7f600df08a9b447a4d711052d7cfe63a11eb8372aa670188b2795200000000000000000000000000000000000000000000000000000000"
\]
},
{
"to": "0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2",
"operation": "0",
"value": "0.0",
"data": "0xb47204770000000000000000000000004a4fc40d2475f493eca3ec436b924237aa1b0a7600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000320000000000000000000000000026a024b13b4ca23897ad578264c0ec543f904b9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000002446a761202000000000000000000000000f86896a029f0be45a950e6dff9ddbb39ae2377230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000044b649d12500000000000000000000000000000000000000000000000003dadd9e886b200000000000000000000000000000000000000000000000043c33c1937564800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041000000000000000000000000208fb9169bbec5915722e0aff8b0eeedabf8a6f00000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"method": "sendMessageToChild(address,bytes)",
"params": \[
"0x4A4FC40d2475f493EcA3Ec436b924237AA1b0a76",
"0x000000000000000000000000026a024b13b4ca23897ad578264c0ec543f904b9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000002446a761202000000000000000000000000f86896a029f0be45a950e6dff9ddbb39ae2377230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000044b649d12500000000000000000000000000000000000000000000000003dadd9e886b200000000000000000000000000000000000000000000000043c33c1937564800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041000000000000000000000000208fb9169bbec5915722e0aff8b0eeedabf8a6f00000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
\]
}
\]