synapsecns/sanguine

View on GitHub
agents/domains/evm/bondingmanager.go

Summary

Maintainability
A
3 hrs
Test Coverage
// Package evm is the package for evm contract stuff.
//
//nolint:dupl
package evm

import (
    "context"
    "fmt"
    "math/big"

    "github.com/ethereum/go-ethereum/accounts/abi/bind"
    "github.com/ethereum/go-ethereum/common"
    ethTypes "github.com/ethereum/go-ethereum/core/types"
    "github.com/synapsecns/sanguine/agents/contracts/bondingmanager"
    "github.com/synapsecns/sanguine/agents/domains"
    "github.com/synapsecns/sanguine/agents/types"
    "github.com/synapsecns/sanguine/ethergo/chain"
    "github.com/synapsecns/sanguine/ethergo/signer/nonce"
)

// NewBondingManagerContract returns a bound bonding manager contract.
//
//nolint:staticcheck
func NewBondingManagerContract(ctx context.Context, client chain.Chain, bondingManagerAddress common.Address) (domains.BondingManagerContract, error) {
    boundCountract, err := bondingmanager.NewBondingManagerRef(bondingManagerAddress, client)
    if err != nil {
        return nil, fmt.Errorf("could not create %T: %w", &bondingmanager.BondingManagerRef{}, err)
    }

    nonceManager := nonce.NewNonceManager(ctx, client, client.GetBigChainID())
    return bondingManagerContract{
        contract:     boundCountract,
        client:       client,
        nonceManager: nonceManager,
    }, nil
}

type bondingManagerContract struct {
    // contract contains the conract handle
    contract *bondingmanager.BondingManagerRef
    // client contains the evm client
    //nolint: staticcheck
    client chain.Chain
    // nonceManager is the nonce manager used for transacting with the chain
    nonceManager nonce.Manager
}

//nolint:dupl
func (a bondingManagerContract) GetAgentStatus(ctx context.Context, address common.Address) (types.AgentStatus, error) {
    rawStatus, err := a.contract.AgentStatus(&bind.CallOpts{Context: ctx}, address)
    if err != nil {
        return nil, fmt.Errorf("could not retrieve agent status: %w", err)
    }

    agentStatus := types.NewAgentStatus(types.AgentFlagType(rawStatus.Flag), rawStatus.Domain, rawStatus.Index)

    return agentStatus, nil
}

//nolint:dupl
func (a bondingManagerContract) GetAgentRoot(ctx context.Context) ([32]byte, error) {
    agentRoot, err := a.contract.AgentRoot(&bind.CallOpts{Context: ctx})
    if err != nil {
        return [32]byte{}, fmt.Errorf("could not retrieve agent root: %w", err)
    }

    return agentRoot, nil
}

//nolint:dupl
func (a bondingManagerContract) GetProof(ctx context.Context, address common.Address) ([][32]byte, error) {
    proof, err := a.contract.GetProof(&bind.CallOpts{Context: ctx}, address)
    if err != nil {
        return nil, fmt.Errorf("could not retrieve agent proof: %w", err)
    }

    return proof, nil
}

func (a bondingManagerContract) DisputeStatus(ctx context.Context, address common.Address) (disputeStatus domains.DisputeStatus, err error) {
    rawDispute, err := a.contract.DisputeStatus(&bind.CallOpts{Context: ctx}, address)
    if err != nil {
        return domains.DisputeStatus{}, fmt.Errorf("could not retrieve dispute status: %w", err)
    }

    return domains.DisputeStatus{
        DisputeFlag: rawDispute.Flag,
        Rival:       rawDispute.Rival,
        FraudProver: rawDispute.FraudProver,
        DisputePtr:  rawDispute.DisputePtr,
    }, nil
}

func (a bondingManagerContract) GetDispute(ctx context.Context, index *big.Int) (err error) {
    _, err = a.contract.GetDispute(&bind.CallOpts{Context: ctx}, index)
    if err != nil {
        return fmt.Errorf("could not retrieve dispute: %w", err)
    }

    return nil
}

func (a bondingManagerContract) CompleteSlashing(transactor *bind.TransactOpts, domain uint32, agent common.Address, proof [][32]byte) (tx *ethTypes.Transaction, err error) {
    tx, err = a.contract.CompleteSlashing(transactor, domain, agent, proof)
    if err != nil {
        return nil, fmt.Errorf("could not submit state report: %w", err)
    }

    return tx, nil
}

func (a bondingManagerContract) GetDisputeStatus(ctx context.Context, agent common.Address) (disputeStatus types.DisputeStatus, err error) {
    rawStatus, err := a.contract.DisputeStatus(&bind.CallOpts{Context: ctx}, agent)
    if err != nil {
        return nil, fmt.Errorf("could not retrieve dispute status: %w", err)
    }

    disputeStatus = types.NewDisputeStatus(types.DisputeFlagType(rawStatus.Flag), rawStatus.Rival, rawStatus.FraudProver, rawStatus.DisputePtr)
    return disputeStatus, nil
}

func (a bondingManagerContract) GetAgent(ctx context.Context, index *big.Int) (types.AgentStatus, common.Address, error) {
    rawStatus, err := a.contract.GetAgent(&bind.CallOpts{Context: ctx}, index)
    if err != nil {
        return nil, common.Address{}, fmt.Errorf("could not retrieve agent status: %w", err)
    }

    agentStatus := types.NewAgentStatus(types.AgentFlagType(rawStatus.Status.Flag), rawStatus.Status.Domain, rawStatus.Status.Index)

    return agentStatus, rawStatus.Agent, nil
}