Skip to content

Commit

Permalink
feat: change the structure of handlers and other changes
Browse files Browse the repository at this point in the history
  • Loading branch information
henriquemarlon committed Nov 16, 2024
1 parent c8e845d commit 843b86e
Show file tree
Hide file tree
Showing 21 changed files with 241 additions and 138 deletions.
16 changes: 10 additions & 6 deletions internal/domain/entity/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package entity

import (
"errors"
"fmt"

"github.com/ethereum/go-ethereum/common"
)
Expand All @@ -20,11 +21,11 @@ type ContractRepository interface {
}

type Contract struct {
Id uint `json:"id" gorm:"primaryKey"`
Symbol string `json:"symbol,omitempty" gorm:"uniqueIndex;not null"`
Id uint `json:"id" gorm:"primaryKey"`
Symbol string `json:"symbol,omitempty" gorm:"uniqueIndex;not null"`
Address common.Address `json:"address,omitempty" gorm:"type:text;not null"`
CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"`
UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"`
CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"`
UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"`
}

func NewContract(symbol string, address common.Address, createdAt int64) (*Contract, error) {
Expand All @@ -40,8 +41,11 @@ func NewContract(symbol string, address common.Address, createdAt int64) (*Contr
}

func (c *Contract) Validate() error {
if c.Symbol == "" || c.Address == (common.Address{}) {
return ErrInvalidContract
if c.Symbol == "" {
return fmt.Errorf("%w: symbol cannot be empty", ErrInvalidContract)
}
if c.Address == (common.Address{}) {
return fmt.Errorf("%w: address cannot be empty", ErrInvalidContract)
}
return nil
}
47 changes: 34 additions & 13 deletions internal/domain/entity/crowdfunding.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package entity

import (
"errors"
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
Expand All @@ -13,9 +14,19 @@ var (
ErrInvalidCrowdfunding = errors.New("invalid crowdfunding")
)

type CrowdfundingState string

const (
CrowdfundingStateOngoing CrowdfundingState = "ongoing"
CrowdfundingStateClosed CrowdfundingState = "closed"
CrowdfundingStateCanceled CrowdfundingState = "canceled"
CrowdfundingStateSettled CrowdfundingState = "settled"
)

type CrowdfundingRepository interface {
CreateCrowdfunding(crowdfunding *Crowdfunding) (*Crowdfunding, error)
FindCrowdfundingsByCreator(creator common.Address) ([]*Crowdfunding, error)
FindCrowdfundingsByInvestor(investor common.Address) ([]*Crowdfunding, error)
FindCrowdfundingById(id uint) (*Crowdfunding, error)
FindAllCrowdfundings() ([]*Crowdfunding, error)
CloseCrowdfunding(id uint) ([]*Order, error)
Expand All @@ -24,27 +35,19 @@ type CrowdfundingRepository interface {
DeleteCrowdfunding(id uint) error
}

type CrowdfundingState string

const (
CrowdfundingStateOngoing CrowdfundingState = "ongoing"
CrowdfundingStateClosed CrowdfundingState = "closed"
CrowdfundingStateSettled CrowdfundingState = "settled"
)

type Crowdfunding struct {
Id uint `json:"id" gorm:"primaryKey"`
Creator common.Address `json:"creator,omitempty" gorm:"type:text;not null"`
DebtIssued uint256.Int `json:"debt_issued,omitempty" gorm:"type:bigint;not null"`
MaxInterestRate uint256.Int `json:"max_interest_rate,omitempty" gorm:"type:bigint;not null"`
DebtIssued *uint256.Int `json:"debt_issued,omitempty" gorm:"type:bigint;not null"`
MaxInterestRate *uint256.Int `json:"max_interest_rate,omitempty" gorm:"type:bigint;not null"`
State CrowdfundingState `json:"state,omitempty" gorm:"type:text;not null"`
Orders []*Order `json:"orders,omitempty" gorm:"foreignKey:CrowdfundingId;constraint:OnDelete:CASCADE"`
ExpiresAt int64 `json:"expires_at,omitempty" gorm:"not null"`
CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"`
UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"`
}

func NewCrowdfunding(creator common.Address, debt_issued uint256.Int, maxInterestRate uint256.Int, expiresAt int64, createdAt int64) (*Crowdfunding, error) {
func NewCrowdfunding(creator common.Address, debt_issued *uint256.Int, maxInterestRate *uint256.Int, expiresAt int64, createdAt int64) (*Crowdfunding, error) {
crowdfunding := &Crowdfunding{
Creator: creator,
DebtIssued: debt_issued,
Expand All @@ -60,8 +63,26 @@ func NewCrowdfunding(creator common.Address, debt_issued uint256.Int, maxInteres
}

func (a *Crowdfunding) Validate() error {
if a.Creator == (common.Address{}) || a.DebtIssued.Sign() == 0 || a.MaxInterestRate.Sign() == 0 || a.ExpiresAt == 0 || a.CreatedAt == 0 || a.CreatedAt >= a.ExpiresAt {
return ErrInvalidCrowdfunding
if a.Creator == (common.Address{}) {
return fmt.Errorf("%w: invalid creator address", ErrInvalidCrowdfunding)
}
if a.DebtIssued.Sign() == 0 {
return fmt.Errorf("%w: debt issued cannot be zero", ErrInvalidCrowdfunding)
}
if a.DebtIssued.Cmp(uint256.NewInt(15000000000)) > 0 {
return fmt.Errorf("%w: debt issued exceeds the maximum allowed value", ErrInvalidCrowdfunding)
}
if a.MaxInterestRate.Sign() == 0 {
return fmt.Errorf("%w: max interest rate cannot be zero", ErrInvalidCrowdfunding)
}
if a.ExpiresAt == 0 {
return fmt.Errorf("%w: expiration date is missing", ErrInvalidCrowdfunding)
}
if a.CreatedAt == 0 {
return fmt.Errorf("%w: creation date is missing", ErrInvalidCrowdfunding)
}
if a.CreatedAt >= a.ExpiresAt {
return fmt.Errorf("%w: creation date cannot be greater than or equal to expiration date", ErrInvalidCrowdfunding)
}
return nil
}
8 changes: 4 additions & 4 deletions internal/domain/entity/crowdfunding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestNewCrowdfunding(t *testing.T) {
createdAt := time.Now().Unix()
expiresAt := createdAt + 3600

crowdfunding, err := NewCrowdfunding(creator, *debt_issued, *interestRate, expiresAt, createdAt)
crowdfunding, err := NewCrowdfunding(creator, debt_issued, interestRate, expiresAt, createdAt)
assert.NoError(t, err)
assert.NotNil(t, crowdfunding)
assert.Equal(t, *debt_issued, crowdfunding.DebtIssued)
Expand All @@ -33,15 +33,15 @@ func TestNewCrowdfunding_Fail_InvalidCrowdfunding(t *testing.T) {
createdAt := time.Now().Unix()
expiresAt := createdAt + 3600

crowdfunding, err := NewCrowdfunding(creator, *debt_issued, *interestRate, expiresAt, createdAt)
crowdfunding, err := NewCrowdfunding(creator, debt_issued, interestRate, expiresAt, createdAt)
assert.Error(t, err)
assert.Nil(t, crowdfunding)
assert.Equal(t, ErrInvalidCrowdfunding, err)

debt_issued = uint256.NewInt(100)
interestRate = uint256.NewInt(0)

crowdfunding, err = NewCrowdfunding(creator, *debt_issued, *interestRate, expiresAt, createdAt)
crowdfunding, err = NewCrowdfunding(creator, debt_issued, interestRate, expiresAt, createdAt)
assert.Error(t, err)
assert.Nil(t, crowdfunding)
assert.Equal(t, ErrInvalidCrowdfunding, err)
Expand All @@ -50,7 +50,7 @@ func TestNewCrowdfunding_Fail_InvalidCrowdfunding(t *testing.T) {
interestRate = uint256.NewInt(50)
expiresAt = createdAt

crowdfunding, err = NewCrowdfunding(creator, *debt_issued, *interestRate, expiresAt, createdAt)
crowdfunding, err = NewCrowdfunding(creator, debt_issued, interestRate, expiresAt, createdAt)
assert.Error(t, err)
assert.Nil(t, crowdfunding)
assert.Equal(t, ErrInvalidCrowdfunding, err)
Expand Down
44 changes: 29 additions & 15 deletions internal/domain/entity/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package entity

import (
"errors"
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
Expand All @@ -12,16 +13,6 @@ var (
ErrOrderNotFound = errors.New("order not found")
)

type OrderRepository interface {
CreateOrder(order *Order) (*Order, error)
FindOrdersByState(crowdfundingId uint, state string) ([]*Order, error)
FindOrderById(id uint) (*Order, error)
FindOrdersByCrowdfundingId(id uint) ([]*Order, error)
FindAllOrders() ([]*Order, error)
UpdateOrder(order *Order) (*Order, error)
DeleteOrder(id uint) error
}

type OrderState string

const (
Expand All @@ -32,18 +23,29 @@ const (
OrderStatePaid OrderState = "paid"
)

type OrderRepository interface {
CreateOrder(order *Order) (*Order, error)
FindOrderById(id uint) (*Order, error)
FindOrdersByCrowdfundingId(id uint) ([]*Order, error)
FindOrdersByState(crowdfundingId uint, state string) ([]*Order, error)
FindOrdersByInvestor(investor common.Address) ([]*Order, error)
FindAllOrders() ([]*Order, error)
UpdateOrder(order *Order) (*Order, error)
DeleteOrder(id uint) error
}

type Order struct {
Id uint `json:"id" gorm:"primaryKey"`
CrowdfundingId uint `json:"crowdfunding_id" gorm:"not null;index"`
Investor common.Address `json:"investor,omitempty" gorm:"not null"`
Amount uint256.Int `json:"amount,omitempty" gorm:"type:bigint;not null"`
InterestRate uint256.Int `json:"interest_rate,omitempty" gorm:"type:bigint;not null"`
Amount *uint256.Int `json:"amount,omitempty" gorm:"type:bigint;not null"`
InterestRate *uint256.Int `json:"interest_rate,omitempty" gorm:"type:bigint;not null"`
State OrderState `json:"state,omitempty" gorm:"type:text;not null"`
CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"`
UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"`
}

func NewOrder(crowdfundingId uint, investor common.Address, amount uint256.Int, interestRate uint256.Int, createdAt int64) (*Order, error) {
func NewOrder(crowdfundingId uint, investor common.Address, amount *uint256.Int, interestRate *uint256.Int, createdAt int64) (*Order, error) {
order := &Order{
CrowdfundingId: crowdfundingId,
Investor: investor,
Expand All @@ -59,8 +61,20 @@ func NewOrder(crowdfundingId uint, investor common.Address, amount uint256.Int,
}

func (b *Order) Validate() error {
if b.CrowdfundingId == 0 || b.Investor == (common.Address{}) || b.Amount.Sign() == 0 || b.InterestRate.Sign() == 0 {
return ErrInvalidOrder
if b.CrowdfundingId == 0 {
return fmt.Errorf("%w: crowdfunding ID cannot be zero", ErrInvalidOrder)
}
if b.Investor == (common.Address{}) {
return fmt.Errorf("%w: investor address cannot be empty", ErrInvalidOrder)
}
if b.Amount.Sign() == 0 {
return fmt.Errorf("%w: amount cannot be zero", ErrInvalidOrder)
}
if b.InterestRate.Sign() == 0 {
return fmt.Errorf("%w: interest rate cannot be zero", ErrInvalidOrder)
}
if b.CreatedAt == 0 {
return fmt.Errorf("%w: creation date is missing", ErrInvalidCrowdfunding)
}
return nil
}
10 changes: 5 additions & 5 deletions internal/domain/entity/order_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestNewOrder_Success(t *testing.T) {
interestRate := uint256.NewInt(50)
createdAt := time.Now().Unix()

order, err := NewOrder(crowdfundingId, investor, *amount, *interestRate, createdAt)
order, err := NewOrder(crowdfundingId, investor, amount, interestRate, createdAt)
assert.NoError(t, err)
assert.NotNil(t, order)
assert.Equal(t, crowdfundingId, order.CrowdfundingId)
Expand All @@ -34,31 +34,31 @@ func TestNewOrder_Fail_InvalidOrder(t *testing.T) {
interestRate := uint256.NewInt(50)
createdAt := time.Now().Unix()

order, err := NewOrder(crowdfundingId, investor, *amount, *interestRate, createdAt)
order, err := NewOrder(crowdfundingId, investor, amount, interestRate, createdAt)
assert.Error(t, err)
assert.Nil(t, order)
assert.Equal(t, ErrInvalidOrder, err)

crowdfundingId = uint(1)
investor = common.Address{}

order, err = NewOrder(crowdfundingId, investor, *amount, *interestRate, createdAt)
order, err = NewOrder(crowdfundingId, investor, amount, interestRate, createdAt)
assert.Error(t, err)
assert.Nil(t, order)
assert.Equal(t, ErrInvalidOrder, err)

investor = common.HexToAddress("0x123")
amount = uint256.NewInt(0)

order, err = NewOrder(crowdfundingId, investor, *amount, *interestRate, createdAt)
order, err = NewOrder(crowdfundingId, investor, amount, interestRate, createdAt)
assert.Error(t, err)
assert.Nil(t, order)
assert.Equal(t, ErrInvalidOrder, err)

amount = uint256.NewInt(100)
interestRate = uint256.NewInt(0)

order, err = NewOrder(crowdfundingId, investor, *amount, *interestRate, createdAt)
order, err = NewOrder(crowdfundingId, investor, amount, interestRate, createdAt)
assert.Error(t, err)
assert.Nil(t, order)
assert.Equal(t, ErrInvalidOrder, err)
Expand Down
55 changes: 44 additions & 11 deletions internal/domain/entity/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package entity

import (
"errors"
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
)

var (
Expand All @@ -22,25 +24,30 @@ const (

type UserRepository interface {
CreateUser(User *User) (*User, error)
FindUserByRole(role string) (*User, error)
FindUsersByRole(role string) ([]*User, error)
FindUserByAddress(address common.Address) (*User, error)
FindAllUsers() ([]*User, error)
UpdateUser(User *User) (*User, error)
DeleteUser(address common.Address) error
}

type User struct {
Id uint `json:"id" gorm:"primaryKey"`
Role string `json:"role,omitempty" gorm:"not null"`
Address common.Address `json:"address,omitempty" gorm:"type:text;uniqueIndex;not null"`
CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"`
UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"`
Id uint `json:"id" gorm:"primaryKey"`
Role string `json:"role,omitempty" gorm:"not null"`
Address common.Address `json:"address,omitempty" gorm:"type:text;uniqueIndex;not null"`
InvestmentLimit *uint256.Int `json:"investment_limit,omitempty" gorm:"type:bigint;not null"`
DebtIssuanceLimit *uint256.Int `json:"debt_issuance_limit,omitempty" gorm:"type:bigint;not null"`
CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"`
UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"`
}

func NewUser(role string, address common.Address, created_at int64) (*User, error) {
user := &User{
Role: role,
Address: address,
CreatedAt: created_at,
Role: role,
InvestmentLimit: setInvestimentLimit(role),
DebtIssuanceLimit: setDebtIssuanceLimit(role),
Address: address,
CreatedAt: created_at,
}
if err := user.Validate(); err != nil {
return nil, err
Expand All @@ -49,8 +56,34 @@ func NewUser(role string, address common.Address, created_at int64) (*User, erro
}

func (u *User) Validate() error {
if u.Role == "" || u.Address == (common.Address{}) {
return ErrInvalidUser
if u.Role == "" {
return fmt.Errorf("%w: role cannot be empty", ErrInvalidUser)
}
if u.Address == (common.Address{}) {
return fmt.Errorf("%w: address cannot be empty", ErrInvalidUser)
}
if u.CreatedAt == 0 {
return fmt.Errorf("%w: creation date is missing", ErrInvalidCrowdfunding)
}
return nil
}

func setInvestimentLimit(role string) *uint256.Int {
switch role {
case string(UserRoleQualifiedInvestor):
return new(uint256.Int).SetAllOne() //According to CVM Resolution 88
case string(UserRoleNonQualifiedInvestor):
return uint256.NewInt(20000) //According to CVM Resolution 88
default:
return uint256.NewInt(0)
}
}

func setDebtIssuanceLimit(role string) *uint256.Int {
switch role {
case string(UserRoleCreator):
return uint256.NewInt(15000000) //According to CVM Resolution 88
default:
return uint256.NewInt(0)
}
}
Loading

0 comments on commit 843b86e

Please sign in to comment.