Skip to content

Commit

Permalink
Remvoing ctf v2 dep and deploying token and pool using Burn and Mint
Browse files Browse the repository at this point in the history
  • Loading branch information
b-gopalswami committed Dec 5, 2024
1 parent dd22875 commit 908ec33
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ func (params CCIPJobSpecParams) ExecutionJobSpec() (*OCR2TaskJobSpec, error) {
}
if params.LBTCConfig != nil {
ocrSpec.PluginConfig["LBTCConfig.AttestationAPI"] = fmt.Sprintf(`"%s"`, params.LBTCConfig.AttestationAPI)
ocrSpec.PluginConfig["LBTCConfig.SourceTokenAddress"] = fmt.Sprintf(`"%s"`, params.LBTCConfig.SourceTokenAddress)
ocrSpec.PluginConfig["LBTCConfig.SourceTokenAddress"] = fmt.Sprintf("\"%s\"", params.LBTCConfig.SourceTokenAddress)
ocrSpec.PluginConfig["LBTCConfig.AttestationAPITimeoutSeconds"] = params.LBTCConfig.AttestationAPITimeoutSeconds
}
return &OCR2TaskJobSpec{
Expand Down
97 changes: 54 additions & 43 deletions integration-tests/ccip-tests/actions/ccip_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@ import (
"golang.org/x/exp/rand"
"golang.org/x/sync/errgroup"

"github.com/smartcontractkit/chainlink-testing-framework/framework"
"github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr"

chainselectors "github.com/smartcontractkit/chain-selectors"

"github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr"

commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake"
"github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain"
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/lib/client"
ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env"
Expand Down Expand Up @@ -935,8 +933,8 @@ func (ccipModule *CCIPCommon) DeployContracts(
return fmt.Errorf("granting minter role to token transmitter shouldn't fail %w", err)
}
} else if ccipModule.IsLBTCDeployment() && i == 0 {
// if it's USDC deployment, we deploy the burn mint token 677 with decimal 6 and cast it to ERC20Token
lbtcToken, err := ccipModule.tokenDeployer.DeployBurnMintERC677(new(big.Int).Mul(big.NewInt(1e6), big.NewInt(1e18)))
// if it's LBTC deployment, we deploy the burn mint token 677 with decimal 8 and cast it to ERC20Token
lbtcToken, err := ccipModule.tokenDeployer.DeployCustomBurnMintERC677Token("Lombard LBTC", "LBTC", uint8(18), new(big.Int).Mul(big.NewInt(1e6), big.NewInt(1e18)))
if err != nil {
return fmt.Errorf("deploying bridge lbtc token contract shouldn't fail %w", err)
}
Expand Down Expand Up @@ -1008,6 +1006,13 @@ func (ccipModule *CCIPCommon) DeployContracts(
}

ccipModule.BridgeTokenPools = append(ccipModule.BridgeTokenPools, usdcPool)
} else if ccipModule.IsLBTCDeployment() && i == 0 {
lbtcPool, err := ccipModule.tokenDeployer.DeployBurnAndMintTokenPoolContract(token.Address(), *ccipModule.RMNContract, ccipModule.Router.Instance.Address())
if err != nil {
return fmt.Errorf("deploying burn and mint bridge Token pool(lbtc) shouldn't fail %w", err)
}

ccipModule.BridgeTokenPools = append(ccipModule.BridgeTokenPools, lbtcPool)
} else {
// deploy lock release token pool in case of non-usdc deployment
btp, err := ccipModule.tokenDeployer.DeployLockReleaseTokenPoolContract(token.Address(), *ccipModule.RMNContract, ccipModule.Router.Instance.Address())
Expand Down Expand Up @@ -1306,6 +1311,7 @@ func DefaultCCIPModule(
ExistingDeployment: pointer.GetBool(testGroupConf.ExistingDeployment),
MulticallEnabled: pointer.GetBool(testGroupConf.MulticallInOneTx),
USDCMockDeployment: testGroupConf.USDCMockDeployment,
LBTCMockDeployment: testGroupConf.LBTCMockDeployment,
NoOfTokensNeedingDynamicPrice: pointer.GetInt(testGroupConf.TokenConfig.NoOfTokensWithDynamicPrice),
poolFunds: testhelpers.Link(5),
gasUpdateWatcherMu: &sync.Mutex{},
Expand Down Expand Up @@ -3755,7 +3761,7 @@ func (lane *CCIPLane) DeployNewCCIPLane(
}
if !lane.Source.Common.ExistingDeployment && lane.Source.Common.IsLBTCDeployment() {
api := "/bridge/v1/deposits/getByHash"
url := framework.HostDockerInternal() + api
url := "http://localhost:8080" + api //framework.HostDockerInternal() +
// Only one LBTC allowed per chain
jobParams.LBTCConfig = &config.LBTCConfig{
SourceTokenAddress: common.HexToAddress(lane.Source.Common.BridgeTokens[0].Address()),
Expand Down Expand Up @@ -4455,48 +4461,53 @@ func SetMockServerWithUSDCAttestation(
// The path is set with regex to match any path that starts with /v1/attestations
func SetMockServerWithLBTCAttestation() error {
apiPath := "/bridge/v1/deposits/getByHash"
cfg := &fake.Input{
Port: 9111,
}
out, err := fake.NewFakeDataProvider(cfg)
if err != nil {
return fmt.Errorf("failed to create fake data provider: %w", err)
}
path := out.BaseURLDocker + apiPath
service := gin.Default()
//Service.Use(recordMiddleware())
go func() {
_ = service.Run("http://localhost:8080")
}()
//out := &Output{
// BaseURLHost: fmt.Sprintf("http://localhost:%d", in.Port),
// BaseURLDocker: fmt.Sprintf("%s:%d", framework.HostDockerInternal(), in.Port),
//}
//in.Out = out
//return out, nil
//out, err := fake.NewFakeDataProvider(cfg)
//if err != nil {
// return fmt.Errorf("failed to create fake data provider: %w", err)
//}
path := "" + apiPath //out.BaseURLDocker + apiPath
method := "POST"
err = fake.Func(
method,
apiPath,
func(c *gin.Context) {
var requestBody struct {
MessageHashes []string `json:"messageHash"`
}
if err := c.ShouldBindJSON(&requestBody); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid JSON"})
return
}
service.Handle(method, path, func(c *gin.Context) {
var requestBody struct {
MessageHashes []string `json:"messageHash"`
}
if err := c.ShouldBindJSON(&requestBody); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid JSON"})
return
}

// You can log the request body or process it if needed
fmt.Println("Received messageHash:", requestBody.MessageHashes[0])
// You can log the request body or process it if needed
fmt.Println("Received messageHash:", requestBody.MessageHashes[0])

// Mock response body based on the request
mockResponse := gin.H{
"attestations": []map[string]any{
{
"message_hash": requestBody.MessageHashes[0],
"status": "NOTARIZATION_STATUS_SESSION_APPROVED",
"attestation": "0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000e45c70a5050000000000000000000000000000000000000000000000000000000000aa36a7000000000000000000000000845f8e3c214d8d0e4d83fc094f302aa26a12a0bc0000000000000000000000000000000000000000000000000000000000014a34000000000000000000000000845f8e3c214d8d0e4d83fc094f302aa26a12a0bc00000000000000000000000062f10ce5b727edf787ea45776bd050308a61150800000000000000000000000000000000000000000000000000000000000003e60000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000040277eeafba008d767c2636d9428f2ebb13ab29ac70337f4fc34b0f5606767cae546f9be3f12160de6d142e5b3c1c3ebd0bf4298662b32b597d0cc5970c7742fc10000000000000000000000000000000000000000000000000000000000000040bbcd60ecc9e06f2effe7c94161219498a1eb435b419387adadb86ec9a52dfb066ce027532517df7216404049d193a25b85c35edfa3e7c5aa4757bfe84887a3980000000000000000000000000000000000000000000000000000000000000040da4a6dc619b5ca2349783cabecc4efdbc910090d3e234d7b8d0430165f8fae532f9a965ceb85c18bb92e059adefa7ce5835850a705761ab9e026d2db4a13ef9a",
},
// Mock response body based on the request
mockResponse := gin.H{
"attestations": []map[string]any{
{
"message_hash": requestBody.MessageHashes[0],
"status": "NOTARIZATION_STATUS_SESSION_APPROVED",
"attestation": "0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000e45c70a5050000000000000000000000000000000000000000000000000000000000aa36a7000000000000000000000000845f8e3c214d8d0e4d83fc094f302aa26a12a0bc0000000000000000000000000000000000000000000000000000000000014a34000000000000000000000000845f8e3c214d8d0e4d83fc094f302aa26a12a0bc00000000000000000000000062f10ce5b727edf787ea45776bd050308a61150800000000000000000000000000000000000000000000000000000000000003e60000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000040277eeafba008d767c2636d9428f2ebb13ab29ac70337f4fc34b0f5606767cae546f9be3f12160de6d142e5b3c1c3ebd0bf4298662b32b597d0cc5970c7742fc10000000000000000000000000000000000000000000000000000000000000040bbcd60ecc9e06f2effe7c94161219498a1eb435b419387adadb86ec9a52dfb066ce027532517df7216404049d193a25b85c35edfa3e7c5aa4757bfe84887a3980000000000000000000000000000000000000000000000000000000000000040da4a6dc619b5ca2349783cabecc4efdbc910090d3e234d7b8d0430165f8fae532f9a965ceb85c18bb92e059adefa7ce5835850a705761ab9e026d2db4a13ef9a",
},
}
},
}

// Return the mocked response
c.JSON(http.StatusOK, mockResponse)
},
// Return the mocked response
c.JSON(http.StatusOK, mockResponse)
},
)
if err != nil {
return fmt.Errorf("failed to create mock response: %w", err)
}
//if err != nil {
// return fmt.Errorf("failed to create mock response: %w", err)
//}
log.Info().Str("path", path).Msg("setting attestation-api response for any msgHash")
return nil
}
Expand Down
97 changes: 97 additions & 0 deletions integration-tests/ccip-tests/contracts/contract_deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain"
burn_mint_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0"

"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
Expand Down Expand Up @@ -241,6 +242,43 @@ func (e *CCIPContractsDeployer) DeployBurnMintERC677(ownerMintingAmount *big.Int
return token, err
}

func (e *CCIPContractsDeployer) DeployCustomBurnMintERC677Token(name, symbol string, decimals uint8, ownerMintingAmount *big.Int) (*ERC677Token, error) {
address, _, instance, err := e.evmClient.DeployContract("Burn Mint ERC 677", func(
auth *bind.TransactOpts,
_ bind.ContractBackend,
) (common.Address, *types.Transaction, interface{}, error) {
return burn_mint_erc677.DeployBurnMintERC677(auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil), name, symbol, decimals, new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e9)))
})
if err != nil {
return nil, err
}

token := &ERC677Token{
client: e.evmClient,
logger: e.logger,
ContractAddress: *address,
instance: instance.(*burn_mint_erc677.BurnMintERC677),
OwnerAddress: common.HexToAddress(e.evmClient.GetDefaultWallet().Address()),
OwnerWallet: e.evmClient.GetDefaultWallet(),
}
if ownerMintingAmount != nil {
// grant minter role to owner and mint tokens
err = token.GrantMintRole(common.HexToAddress(e.evmClient.GetDefaultWallet().Address()))
if err != nil {
return token, fmt.Errorf("granting minter role to owner shouldn't fail %w", err)
}
err = e.evmClient.WaitForEvents()
if err != nil {
return token, fmt.Errorf("error in waiting for granting mint role %w", err)
}
err = token.Mint(common.HexToAddress(e.evmClient.GetDefaultWallet().Address()), ownerMintingAmount)
if err != nil {
return token, fmt.Errorf("minting tokens shouldn't fail %w", err)
}
}
return token, err
}

func (e *CCIPContractsDeployer) DeployERC20TokenContract(deployerFn blockchain.ContractDeployer) (*ERC20Token, error) {
address, _, _, err := e.evmClient.DeployContract("Custom ERC20 Token", deployerFn)
if err != nil {
Expand Down Expand Up @@ -488,6 +526,65 @@ func (e *CCIPContractsDeployer) DeployUSDCTokenPoolContract(tokenAddr string, to
}
}

func (e *CCIPContractsDeployer) DeployBurnAndMintTokenPoolContract(tokenAddr string, rmnProxy common.Address, router common.Address) (
*TokenPool,
error,
) {
version := VersionMap[TokenPoolContract]
e.logger.Debug().Str("Token", tokenAddr).Msg("Deploying Burn and Mint token pool")
token := common.HexToAddress(tokenAddr)
switch version {
case Latest:
address, _, _, err := e.evmClient.DeployContract("Burn and Mint Token Pool", func(
auth *bind.TransactOpts,
_ bind.ContractBackend,
) (common.Address, *types.Transaction, interface{}, error) {
return burn_mint_token_pool.DeployBurnMintTokenPool(
auth,
wrappers.MustNewWrappedContractBackend(e.evmClient, nil),
token,
[]common.Address{},
rmnProxy,
router,
)
})

if err != nil {
return nil, err
}
pool, err := burn_mint_token_pool.NewBurnMintTokenPool(*address, wrappers.MustNewWrappedContractBackend(e.evmClient, nil))

if err != nil {
return nil, err
}
e.logger.Info().
Str("Contract Address", address.Hex()).
Str("Contract Name", "USDC Token Pool").
Str("From", e.evmClient.GetDefaultWallet().Address()).
Str("Network Name", e.evmClient.GetNetworkConfig().Name).
Msg("New contract")
poolInterface, err := token_pool.NewTokenPool(*address, wrappers.MustNewWrappedContractBackend(e.evmClient, nil))
if err != nil {
return nil, err
}
return &TokenPool{
client: e.evmClient,
logger: e.logger,
Instance: &TokenPoolWrapper{
Latest: &LatestPool{
PoolInterface: poolInterface,
BurnAndMintTokenPool: pool,
},
},
EthAddress: *address,
OwnerAddress: common.HexToAddress(e.evmClient.GetDefaultWallet().Address()),
OwnerWallet: e.evmClient.GetDefaultWallet(),
}, err
default:
return nil, fmt.Errorf("version not supported: %s", version)
}
}

func (e *CCIPContractsDeployer) DeployLockReleaseTokenPoolContract(tokenAddr string, rmnProxy common.Address, router common.Address) (
*TokenPool,
error,
Expand Down
8 changes: 5 additions & 3 deletions integration-tests/ccip-tests/contracts/contract_models.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"golang.org/x/exp/rand"

"github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain"
burn_mint_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0"

"github.com/smartcontractkit/chainlink/integration-tests/wrappers"

Expand Down Expand Up @@ -401,9 +402,10 @@ func (l *LinkToken) Transfer(to string, amount *big.Int) error {
}

type LatestPool struct {
PoolInterface *token_pool.TokenPool
LockReleasePool *lock_release_token_pool.LockReleaseTokenPool
USDCPool *usdc_token_pool.USDCTokenPool
PoolInterface *token_pool.TokenPool
BurnAndMintTokenPool *burn_mint_token_pool.BurnMintTokenPool
LockReleasePool *lock_release_token_pool.LockReleaseTokenPool
USDCPool *usdc_token_pool.USDCTokenPool
}

type V1_4_0Pool struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ EIP1559FeeCapBufferBlocks = 0

# Run by default using latest version from `ccip-develop` branch, override this value to use a specific version
[CCIP.Env.NewCLCluster.Common.ChainlinkImage]
version = "ccip-develop"
version = "latest"

# the following configs are specific to each test type, smoke, load , chaos, etc...
[CCIP.Groups]
Expand Down Expand Up @@ -268,16 +268,16 @@ LBTCMockDeployment = true
MsgType = 'DataWithToken' # type of message to be sent, either 'Token' or 'DataWithToken' Or 'Data'
DestGasLimit = 100000 # change this to 0 gas limit if you are doing ccip-send to an EOA
DataLength = 1000 # length of the data to be sent in ccip message if MsgType = 'Data'/'DataWithToken'
NoOfTokens = 2 # number of bridge tokens to be sent in ccip message if MsgType = 'Token'/'DataWithToken'
NoOfTokens = 1 # number of bridge tokens to be sent in ccip message if MsgType = 'Token'/'DataWithToken'
AmountPerToken = 1 # amount to be sent for each bridge token in ccip message if MsgType = 'Token'/'DataWithToken'

[CCIP.Groups.smoke.TokenConfig]
TimeoutForPriceUpdate = '15m' # Duration to wait for the price update to time-out.
# Now testing only with dynamic price getter (no pipeline).
# Could be removed once the pipeline is completely removed.
WithPipeline = false
NoOfTokensPerChain = 2 # number of bridge tokens to be deployed per network; if MsgType = 'Token'/'DataWithToken'
CCIPOwnerTokens = false # if true, the test will use deploy the tokens by the CCIPOwner, otherwise the tokens will be deployed by a non-owner account, only applicable for 1.5 pools and onwards
NoOfTokensPerChain = 1 # number of bridge tokens to be deployed per network; if MsgType = 'Token'/'DataWithToken'
CCIPOwnerTokens = true # if true, the test will use deploy the tokens by the CCIPOwner, otherwise the tokens will be deployed by a non-owner account, only applicable for 1.5 pools and onwards

#NoOfTokensWithDynamicPrice = 15 # number of tokens with dynamic price to be deployed
#DynamicPriceUpdateInterval ='15s' # Periodic interval to update the price of tokens, if there are tokens with dynamic price
Expand Down

0 comments on commit 908ec33

Please sign in to comment.