70 lines
2.0 KiB
Go
70 lines
2.0 KiB
Go
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))
|
|
}
|