{
    "version": "0.0.1",
    "name": "merkle_distributor",
    "instructions": [
        {
            "name": "newDistributor",
            "docs": [
                "READ THE FOLLOWING:",
                "",
                "This instruction is susceptible to frontrunning that could result in loss of funds if not handled properly.",
                "",
                "An attack could look like:",
                "- A legitimate user opens a new distributor.",
                "- Someone observes the call to this instruction.",
                "- They replace the clawback_receiver, admin, or time parameters with their own.",
                "",
                "One situation that could happen here is the attacker replaces the admin and clawback_receiver with their own",
                "and sets the clawback_start_ts with the minimal time allowed. After clawback_start_ts has elapsed,",
                "the attacker can steal all funds from the distributor to their own clawback_receiver account.",
                "",
                "HOW TO AVOID:",
                "- When you call into this instruction, ensure your transaction succeeds.",
                "- To be extra safe, after your transaction succeeds, read back the state of the created MerkleDistributor account and",
                "assert the parameters are what you expect, most importantly the clawback_receiver and admin.",
                "- If your transaction fails, double check the value on-chain matches what you expect."
            ],
            "accounts": [
                {
                    "name": "distributor",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "[MerkleDistributor]."
                    ],
                    "pda": {
                        "seeds": [
                            {
                                "kind": "const",
                                "type": "string",
                                "value": "MerkleDistributor"
                            },
                            {
                                "kind": "account",
                                "type": "publicKey",
                                "account": "Mint",
                                "path": "mint"
                            },
                            {
                                "kind": "arg",
                                "type": "u64",
                                "path": "version"
                            }
                        ]
                    }
                },
                {
                    "name": "clawbackReceiver",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "Clawback receiver token account"
                    ]
                },
                {
                    "name": "mint",
                    "isMut": false,
                    "isSigner": false,
                    "docs": [
                        "The mint to distribute."
                    ]
                },
                {
                    "name": "tokenVault",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "Token vault"
                    ]
                },
                {
                    "name": "admin",
                    "isMut": true,
                    "isSigner": true,
                    "docs": [
                        "Admin wallet, responsible for creating the distributor and paying for the transaction.",
                        "Also has the authority to set the clawback receiver and change itself."
                    ]
                },
                {
                    "name": "systemProgram",
                    "isMut": false,
                    "isSigner": false,
                    "docs": [
                        "The [System] program."
                    ]
                },
                {
                    "name": "associatedTokenProgram",
                    "isMut": false,
                    "isSigner": false,
                    "docs": [
                        "The [Associated Token] program."
                    ]
                },
                {
                    "name": "tokenProgram",
                    "isMut": false,
                    "isSigner": false,
                    "docs": [
                        "The [Token] program."
                    ]
                }
            ],
            "args": [
                {
                    "name": "version",
                    "type": "u64"
                },
                {
                    "name": "root",
                    "type": {
                        "array": [
                            "u8",
                            32
                        ]
                    }
                },
                {
                    "name": "maxTotalClaim",
                    "type": "u64"
                },
                {
                    "name": "maxNumNodes",
                    "type": "u64"
                },
                {
                    "name": "startVestingTs",
                    "type": "i64"
                },
                {
                    "name": "endVestingTs",
                    "type": "i64"
                },
                {
                    "name": "clawbackStartTs",
                    "type": "i64"
                }
            ]
        },
        {
            "name": "newClaim",
            "accounts": [
                {
                    "name": "distributor",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "The [MerkleDistributor]."
                    ]
                },
                {
                    "name": "claimStatus",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "Claim status PDA"
                    ],
                    "pda": {
                        "seeds": [
                            {
                                "kind": "const",
                                "type": "string",
                                "value": "ClaimStatus"
                            },
                            {
                                "kind": "account",
                                "type": "publicKey",
                                "path": "claimant"
                            },
                            {
                                "kind": "account",
                                "type": "publicKey",
                                "account": "MerkleDistributor",
                                "path": "distributor"
                            }
                        ]
                    }
                },
                {
                    "name": "from",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "Distributor ATA containing the tokens to distribute."
                    ]
                },
                {
                    "name": "to",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "Account to send the claimed tokens to."
                    ]
                },
                {
                    "name": "claimant",
                    "isMut": true,
                    "isSigner": true,
                    "docs": [
                        "Who is claiming the tokens."
                    ]
                },
                {
                    "name": "tokenProgram",
                    "isMut": false,
                    "isSigner": false,
                    "docs": [
                        "SPL [Token] program."
                    ]
                },
                {
                    "name": "systemProgram",
                    "isMut": false,
                    "isSigner": false,
                    "docs": [
                        "The [System] program."
                    ]
                }
            ],
            "args": [
                {
                    "name": "amountUnlocked",
                    "type": "u64"
                },
                {
                    "name": "amountLocked",
                    "type": "u64"
                },
                {
                    "name": "proof",
                    "type": {
                        "vec": {
                            "array": [
                                "u8",
                                32
                            ]
                        }
                    }
                }
            ]
        },
        {
            "name": "claimLocked",
            "accounts": [
                {
                    "name": "distributor",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "The [MerkleDistributor]."
                    ]
                },
                {
                    "name": "claimStatus",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "Claim Status PDA"
                    ],
                    "pda": {
                        "seeds": [
                            {
                                "kind": "const",
                                "type": "string",
                                "value": "ClaimStatus"
                            },
                            {
                                "kind": "account",
                                "type": "publicKey",
                                "path": "claimant"
                            },
                            {
                                "kind": "account",
                                "type": "publicKey",
                                "account": "MerkleDistributor",
                                "path": "distributor"
                            }
                        ]
                    }
                },
                {
                    "name": "from",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "Distributor ATA containing the tokens to distribute."
                    ]
                },
                {
                    "name": "to",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "Account to send the claimed tokens to.",
                        "Claimant must sign the transaction and can only claim on behalf of themself"
                    ]
                },
                {
                    "name": "claimant",
                    "isMut": true,
                    "isSigner": true,
                    "docs": [
                        "Who is claiming the tokens."
                    ]
                },
                {
                    "name": "tokenProgram",
                    "isMut": false,
                    "isSigner": false,
                    "docs": [
                        "SPL [Token] program."
                    ]
                }
            ],
            "args": []
        },
        {
            "name": "clawback",
            "accounts": [
                {
                    "name": "distributor",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "The [MerkleDistributor]."
                    ]
                },
                {
                    "name": "from",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "Distributor ATA containing the tokens to distribute."
                    ]
                },
                {
                    "name": "to",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "The Clawback token account."
                    ]
                },
                {
                    "name": "claimant",
                    "isMut": false,
                    "isSigner": true,
                    "docs": [
                        "Claimant account",
                        "Anyone can claw back the funds"
                    ]
                },
                {
                    "name": "systemProgram",
                    "isMut": false,
                    "isSigner": false,
                    "docs": [
                        "The [System] program."
                    ]
                },
                {
                    "name": "tokenProgram",
                    "isMut": false,
                    "isSigner": false,
                    "docs": [
                        "SPL [Token] program."
                    ]
                }
            ],
            "args": []
        },
        {
            "name": "setClawbackReceiver",
            "accounts": [
                {
                    "name": "distributor",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "The [MerkleDistributor]."
                    ]
                },
                {
                    "name": "newClawbackAccount",
                    "isMut": false,
                    "isSigner": false,
                    "docs": [
                        "New clawback account"
                    ]
                },
                {
                    "name": "admin",
                    "isMut": true,
                    "isSigner": true,
                    "docs": [
                        "Admin signer"
                    ]
                }
            ],
            "args": []
        },
        {
            "name": "setAdmin",
            "accounts": [
                {
                    "name": "distributor",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "The [MerkleDistributor]."
                    ]
                },
                {
                    "name": "admin",
                    "isMut": true,
                    "isSigner": true,
                    "docs": [
                        "Admin signer"
                    ]
                },
                {
                    "name": "newAdmin",
                    "isMut": true,
                    "isSigner": false,
                    "docs": [
                        "New admin account"
                    ]
                }
            ],
            "args": []
        }
    ],
    "accounts": [
        {
            "name": "ClaimStatus",
            "docs": [
                "Holds whether or not a claimant has claimed tokens."
            ],
            "type": {
                "kind": "struct",
                "fields": [
                    {
                        "name": "claimant",
                        "docs": [
                            "Authority that claimed the tokens."
                        ],
                        "type": "publicKey"
                    },
                    {
                        "name": "lockedAmount",
                        "docs": [
                            "Locked amount"
                        ],
                        "type": "u64"
                    },
                    {
                        "name": "lockedAmountWithdrawn",
                        "docs": [
                            "Locked amount withdrawn"
                        ],
                        "type": "u64"
                    },
                    {
                        "name": "unlockedAmount",
                        "docs": [
                            "Unlocked amount"
                        ],
                        "type": "u64"
                    }
                ]
            }
        },
        {
            "name": "MerkleDistributor",
            "docs": [
                "State for the account which distributes tokens."
            ],
            "type": {
                "kind": "struct",
                "fields": [
                    {
                        "name": "bump",
                        "docs": [
                            "Bump seed."
                        ],
                        "type": "u8"
                    },
                    {
                        "name": "version",
                        "docs": [
                            "Version of the airdrop"
                        ],
                        "type": "u64"
                    },
                    {
                        "name": "root",
                        "docs": [
                            "The 256-bit merkle root."
                        ],
                        "type": {
                            "array": [
                                "u8",
                                32
                            ]
                        }
                    },
                    {
                        "name": "mint",
                        "docs": [
                            "[Mint] of the token to be distributed."
                        ],
                        "type": "publicKey"
                    },
                    {
                        "name": "tokenVault",
                        "docs": [
                            "Token Address of the vault"
                        ],
                        "type": "publicKey"
                    },
                    {
                        "name": "maxTotalClaim",
                        "docs": [
                            "Maximum number of tokens that can ever be claimed from this [MerkleDistributor]."
                        ],
                        "type": "u64"
                    },
                    {
                        "name": "maxNumNodes",
                        "docs": [
                            "Maximum number of nodes in [MerkleDistributor]."
                        ],
                        "type": "u64"
                    },
                    {
                        "name": "totalAmountClaimed",
                        "docs": [
                            "Total amount of tokens that have been claimed."
                        ],
                        "type": "u64"
                    },
                    {
                        "name": "numNodesClaimed",
                        "docs": [
                            "Number of nodes that have been claimed."
                        ],
                        "type": "u64"
                    },
                    {
                        "name": "startTs",
                        "docs": [
                            "Lockup time start (Unix Timestamp)"
                        ],
                        "type": "i64"
                    },
                    {
                        "name": "endTs",
                        "docs": [
                            "Lockup time end (Unix Timestamp)"
                        ],
                        "type": "i64"
                    },
                    {
                        "name": "clawbackStartTs",
                        "docs": [
                            "Clawback start (Unix Timestamp)"
                        ],
                        "type": "i64"
                    },
                    {
                        "name": "clawbackReceiver",
                        "docs": [
                            "Clawback receiver"
                        ],
                        "type": "publicKey"
                    },
                    {
                        "name": "admin",
                        "docs": [
                            "Admin wallet"
                        ],
                        "type": "publicKey"
                    },
                    {
                        "name": "clawedBack",
                        "docs": [
                            "Whether or not the distributor has been clawed back"
                        ],
                        "type": "bool"
                    }
                ]
            }
        }
    ],
    "events": [
        {
            "name": "NewClaimEvent",
            "fields": [
                {
                    "name": "claimant",
                    "type": "publicKey",
                    "index": false
                },
                {
                    "name": "timestamp",
                    "type": "i64",
                    "index": false
                }
            ]
        },
        {
            "name": "ClaimedEvent",
            "fields": [
                {
                    "name": "claimant",
                    "type": "publicKey",
                    "index": false
                },
                {
                    "name": "amount",
                    "type": "u64",
                    "index": false
                }
            ]
        }
    ],
    "errors": [
        {
            "code": 6000,
            "name": "InsufficientUnlockedTokens",
            "msg": "Insufficient unlocked tokens"
        },
        {
            "code": 6001,
            "name": "StartTooFarInFuture",
            "msg": "Deposit Start too far in future"
        },
        {
            "code": 6002,
            "name": "InvalidProof",
            "msg": "Invalid Merkle proof."
        },
        {
            "code": 6003,
            "name": "ExceededMaxClaim",
            "msg": "Exceeded maximum claim amount"
        },
        {
            "code": 6004,
            "name": "MaxNodesExceeded",
            "msg": "Exceeded maximum node count"
        },
        {
            "code": 6005,
            "name": "Unauthorized",
            "msg": "Account is not authorized to execute this instruction"
        },
        {
            "code": 6006,
            "name": "OwnerMismatch",
            "msg": "Token account owner did not match intended owner"
        },
        {
            "code": 6007,
            "name": "ClawbackDuringVesting",
            "msg": "Clawback cannot be before vesting ends"
        },
        {
            "code": 6008,
            "name": "ClawbackBeforeStart",
            "msg": "Attempted clawback before start"
        },
        {
            "code": 6009,
            "name": "ClawbackAlreadyClaimed",
            "msg": "Clawback already claimed"
        },
        {
            "code": 6010,
            "name": "InsufficientClawbackDelay",
            "msg": "Clawback start must be at least one day after vesting end"
        },
        {
            "code": 6011,
            "name": "SameClawbackReceiver",
            "msg": "New and old Clawback receivers are identical"
        },
        {
            "code": 6012,
            "name": "SameAdmin",
            "msg": "New and old admin are identical"
        },
        {
            "code": 6013,
            "name": "ClaimExpired",
            "msg": "Claim window expired"
        },
        {
            "code": 6014,
            "name": "ArithmeticError",
            "msg": "Arithmetic Error (overflow/underflow)"
        },
        {
            "code": 6015,
            "name": "StartTimestampAfterEnd",
            "msg": "Start Timestamp cannot be after end Timestamp"
        },
        {
            "code": 6016,
            "name": "TimestampsNotInFuture",
            "msg": "Timestamps cannot be in the past"
        },
        {
            "code": 6017,
            "name": "InvalidVersion",
            "msg": "Airdrop Version Mismatch"
        }
    ]
}
