Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ccip 4408 lbtc mock pool #1562

Draft
wants to merge 6 commits into
base: ccip-develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contracts/scripts/native_solc_compile_all_ccip
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ compileContract ccip/test/helpers/receivers/MaybeRevertMessageReceiver.sol
compileContract ccip/test/helpers/MultiOCR3Helper.sol
compileContract ccip/test/mocks/MockE2EUSDCTokenMessenger.sol
compileContract ccip/test/mocks/MockE2EUSDCTransmitter.sol
compileContract ccip/test/mocks/MockLBTCTokenPool.sol
compileContract ccip/test/WETH9.sol


Expand Down
62 changes: 62 additions & 0 deletions contracts/src/v0.8/ccip/test/mocks/MockLBTCTokenPool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.24;

import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol";

import {Pool} from "../../libraries/Pool.sol";
import {TokenPool} from "../../pools/TokenPool.sol";

import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol";


contract MockLBTCTokenPool is TokenPool, ITypeAndVersion {
using SafeERC20 for IERC20;

string public constant override typeAndVersion = "LBTCTokenPool 1.5.1";

constructor(
IERC20 token,
address[] memory allowlist,
address rmnProxy,
address router
) TokenPool(token, 6, allowlist, rmnProxy, router) {
}

/// @notice Burn the token in the pool
/// @dev The _validateLockOrBurn check is an essential security check
function lockOrBurn(
Pool.LockOrBurnInV1 calldata lockOrBurnIn
) external virtual override returns (Pool.LockOrBurnOutV1 memory) {
bytes memory payload;
bytes memory destPoolData;
payload = abi.encodePacked(hex"1234abcd");
destPoolData = abi.encode(sha256(payload));

return
Pool.LockOrBurnOutV1({
destTokenAddress: getRemoteToken(
lockOrBurnIn.remoteChainSelector
),
destPoolData: destPoolData
});
}

function releaseOrMint(
Pool.ReleaseOrMintInV1 calldata releaseOrMintIn
) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) {

// TODO: validate releaseOrMintIn.offchainTokenData?

emit Minted(
msg.sender,
releaseOrMintIn.receiver,
releaseOrMintIn.amount
);

return
Pool.ReleaseOrMintOutV1({
destinationAmount: releaseOrMintIn.amount
});
}
}
3,018 changes: 3,018 additions & 0 deletions core/gethwrappers/ccip/generated/mock_lbtc_token_pool/mock_lbtc_token_pool.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/Lo
lock_release_token_pool_and_proxy: ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPoolAndProxy/LockReleaseTokenPoolAndProxy.bin e632b08be0fbd1d013e8b3a9d75293d0d532b83071c531ff2be1deec1fa48ec1
maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5
message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin 0a2661da24147160383ad61d56a258515d1cc07f5e0f471ec5cbb4bccaf82389
mock_lbtc_token_pool: ../../../contracts/solc/v0.8.24/MockLBTCTokenPool/MockLBTCTokenPool.abi ../../../contracts/solc/v0.8.24/MockLBTCTokenPool/MockLBTCTokenPool.bin e7d57c256ca3040a190415eeb89afa5850007635d0c0a9be600a9fbee4fb3fa6
mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737
mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin be0dbc3e475741ea0b7a54ec2b935a321b428baa9f4ce18180a87fb38bb87de2
mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4
Expand Down
1 change: 1 addition & 0 deletions core/gethwrappers/ccip/go_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ package ccip
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin WETH9 weth9
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin MockE2EUSDCTokenMessenger mock_usdc_token_messenger
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin MockE2EUSDCTransmitter mock_usdc_token_transmitter
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MockLBTCTokenPool/MockLBTCTokenPool.abi ../../../contracts/solc/v0.8.24/MockLBTCTokenPool/MockLBTCTokenPool.bin MockLBTCTokenPool mock_lbtc_token_pool

// EncodingUtils
//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.abi ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.bin EncodingUtils ccip_encoding_utils
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ type CCIPJobSpecParams struct {
DestStartBlock uint64
USDCAttestationAPI string
USDCConfig *config.USDCConfig
LBTCConfig *config.LBTCConfig
P2PV2Bootstrappers pq.StringArray
}

Expand Down Expand Up @@ -295,6 +296,11 @@ func (params CCIPJobSpecParams) ExecutionJobSpec() (*OCR2TaskJobSpec, error) {
ocrSpec.PluginConfig["USDCConfig.SourceMessageTransmitterAddress"] = fmt.Sprintf(`"%s"`, params.USDCConfig.SourceMessageTransmitterAddress)
ocrSpec.PluginConfig["USDCConfig.AttestationAPITimeoutSeconds"] = params.USDCConfig.AttestationAPITimeoutSeconds
}
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.AttestationAPITimeoutSeconds"] = params.LBTCConfig.AttestationAPITimeoutSeconds
}
return &OCR2TaskJobSpec{
OCR2OracleSpec: ocrSpec,
JobType: "offchainreporting2",
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dvsekhvalnov/jose2go v1.7.0 // indirect
github.com/ethereum/c-kzg-4844 v0.4.0 // indirect
github.com/fjl/memsize v0.0.2 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gagliardetto/binary v0.7.7 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA=
github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
Expand Down
88 changes: 86 additions & 2 deletions integration-tests/ccip-tests/actions/ccip_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ import (
"golang.org/x/exp/rand"
"golang.org/x/sync/errgroup"

"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/lib/blockchain"
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/lib/client"
Expand Down Expand Up @@ -150,6 +150,7 @@ func GetUSDCDomain(networkName string, simulated bool) (uint32, error) {
if val, ok := lookup[networkName]; ok {
return val, nil
}

return 0, fmt.Errorf("USDC domain not found for chain %s", networkName)
}

Expand All @@ -176,6 +177,7 @@ type CCIPCommon struct {
MulticallContract common.Address
ExistingDeployment bool
USDCMockDeployment *bool
LBTCMockDeployment *bool
TokenMessenger *common.Address
TokenTransmitter *contracts.TokenTransmitter
IsConnectionRestoredRecently *atomic.Bool
Expand Down Expand Up @@ -720,6 +722,10 @@ func (ccipModule *CCIPCommon) IsUSDCDeployment() bool {
return pointer.GetBool(ccipModule.USDCMockDeployment)
}

func (ccipModule *CCIPCommon) IsLBTCDeployment() bool {
return pointer.GetBool(ccipModule.LBTCMockDeployment)
}

func (ccipModule *CCIPCommon) WriteLaneConfig(conf *laneconfig.LaneConfig) {
var btAddresses, btpAddresses []string
priceAggrs := make(map[string]string)
Expand Down Expand Up @@ -925,6 +931,16 @@ func (ccipModule *CCIPCommon) DeployContracts(
if err != nil {
return fmt.Errorf("granting minter role to token transmitter shouldn't fail %w", err)
}
} else if ccipModule.IsLBTCDeployment() && i == 1 {
// 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)
}
token, err = ccipModule.tokenDeployer.NewERC20TokenContract(lbtcToken.ContractAddress)
if err != nil {
return fmt.Errorf("getting new bridge lbtc token contract shouldn't fail %w", err)
}
} else {
// otherwise we deploy link token and cast it to ERC20Token
linkToken, err := ccipModule.tokenDeployer.DeployLinkTokenContract()
Expand Down Expand Up @@ -989,6 +1005,13 @@ func (ccipModule *CCIPCommon) DeployContracts(
}

ccipModule.BridgeTokenPools = append(ccipModule.BridgeTokenPools, usdcPool)
} else if ccipModule.IsLBTCDeployment() && i == 1 {
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 @@ -1287,6 +1310,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 @@ -3734,6 +3758,24 @@ func (lane *CCIPLane) DeployNewCCIPLane(
AttestationAPITimeoutSeconds: 5,
}
}
if !lane.Source.Common.ExistingDeployment && lane.Source.Common.IsLBTCDeployment() {
api := ""
if killgrave != nil {
api = killgrave.InternalEndpoint
}
if env.MockServer != nil {
api = env.MockServer.Config.ClusterURL
}
if lane.Source.Common.TokenTransmitter == nil {
return fmt.Errorf("token transmitter address not set")
}
// Only one LBTC allowed per chain
jobParams.LBTCConfig = &config.LBTCConfig{
SourceTokenAddress: common.HexToAddress(lane.Source.Common.BridgeTokens[0].Address()),
AttestationAPI: api,
AttestationAPITimeoutSeconds: 5,
}
}
if !bootstrapAdded.Load() {
bootstrapAdded.Store(true)
err := CreateBootstrapJob(jobParams, bootstrapCommit, bootstrapExec)
Expand Down Expand Up @@ -4422,6 +4464,48 @@ func SetMockServerWithUSDCAttestation(
return nil
}

// SetMockServerWithLBTCAttestation responds with a mock attestation for any msgHash
// The path is set with regex to match any path that starts with /v1/attestations
func SetMockServerWithLBTCAttestation(
killGrave *ctftestenv.Killgrave,
mockserver *ctfClient.MockserverClient,
) error {
path := "/bridge/v1/deposits/getByHash"
type attestation struct {
Status string `json:"status"`
Attestation string `json:"attestation"`
MessageHash string `json:"message_hash"`
}
response := struct {
Attestations []attestation `json:"attestations"`
}{
Attestations: []attestation{
{
MessageHash: "5AAA501FD250E0C88C655C19836A6D71465E908492C5B17C5D8D0260BE905AE9", //sample hash
Status: "NOTARIZATION_STATUS_SESSION_APPROVED",
Attestation: "0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000e45c70a5050000000000000000000000000000000000000000000000000000000000aa36a7000000000000000000000000845f8e3c214d8d0e4d83fc094f302aa26a12a0bc0000000000000000000000000000000000000000000000000000000000014a34000000000000000000000000845f8e3c214d8d0e4d83fc094f302aa26a12a0bc00000000000000000000000062f10ce5b727edf787ea45776bd050308a61150800000000000000000000000000000000000000000000000000000000000003e60000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000040277eeafba008d767c2636d9428f2ebb13ab29ac70337f4fc34b0f5606767cae546f9be3f12160de6d142e5b3c1c3ebd0bf4298662b32b597d0cc5970c7742fc10000000000000000000000000000000000000000000000000000000000000040bbcd60ecc9e06f2effe7c94161219498a1eb435b419387adadb86ec9a52dfb066ce027532517df7216404049d193a25b85c35edfa3e7c5aa4757bfe84887a3980000000000000000000000000000000000000000000000000000000000000040da4a6dc619b5ca2349783cabecc4efdbc910090d3e234d7b8d0430165f8fae532f9a965ceb85c18bb92e059adefa7ce5835850a705761ab9e026d2db4a13ef9a",
},
},
}
if killGrave == nil && mockserver == nil {
return fmt.Errorf("both killgrave and mockserver are nil")
}
log.Info().Str("path", path).Msg("setting attestation-api response for any msgHash")
if killGrave != nil {
err := killGrave.SetAnyValueResponse(path, []string{http.MethodPost}, response)
if err != nil {
return fmt.Errorf("failed to set killgrave server value: %w", err)
}
}
if mockserver != nil {
err := mockserver.SetAnyValueResponse(path, response)
if err != nil {
return fmt.Errorf("failed to set mockserver value: %w URL = %s", err, fmt.Sprintf("%s/%s/.*", mockserver.LocalURL(), path))
}
}
return nil
}

// SetMockserverWithTokenPriceValue sets the mock responses in mockserver that are read by chainlink nodes
// to simulate different price feed value.
// it keeps updating the response every 15 seconds to simulate price feed updates
Expand Down
Loading
Loading