package pancakeswap import ( "context" "math/big" "git.lehouerou.net/laurent/evm" "git.lehouerou.net/laurent/evm/pancakeswap/contracts" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" "github.com/shopspring/decimal" ) const MasterChefAddress = "0x73feaa1eE314F8c655E354234017bE2193C9E24E" type MasterChef struct { client evm.Client contract *contracts.MasterChef cake evm.Token } func NewMasterChef(client evm.Client) (*MasterChef, error) { c, err := contracts.NewMasterChef(common.HexToAddress(MasterChefAddress), client) if err != nil { return nil, errors.Wrap(err, "init contract") } cake, err := client.TokenService().TokenBySymbol("CAKE") if err != nil { return nil, errors.Wrap(err, "finding cake token") } return &MasterChef{ contract: c, client: client, cake: cake, }, nil } func (m *MasterChef) PendingCake(pid int64) (decimal.Decimal, error) { return m.PendingCakeOfAddress(pid, m.client.PublicAddress()) } func (m *MasterChef) PendingCakeOfAddress(pid int64, address common.Address) (decimal.Decimal, error) { raw, err := m.contract.PendingCake(&bind.CallOpts{}, big.NewInt(pid), address) if err != nil { return decimal.Zero, errors.Wrap(err, "calling contract") } return m.cake.ValueFromBigInt(raw), nil } func (m *MasterChef) EnterStaking(ctx context.Context, amount decimal.Decimal) (evm.Transaction, error) { return m.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) { return m.contract.EnterStaking(opts.TransactOpts, m.cake.ValueToBigInt(amount)) }) } func (m *MasterChef) CompoundAndAddCakeBalance(ctx context.Context) (evm.Transaction, error) { pending, err := m.PendingCake(0) if err != nil { return nil, errors.Wrap(err, "getting pending cake reward") } balance, err := m.cake.Balance() if err != nil { return nil, errors.Wrap(err, "getting cake balance") } return m.EnterStaking(ctx, pending.Add(balance)) }