@@ -1399,3 +1399,167 @@ where
13991399 let total_power_response = weighting. total_power_at_height ( None ) . unwrap ( ) ;
14001400 assert_eq ! ( total_power_response. power, power_response_2. power) ;
14011401}
1402+
1403+ pub fn test_release_stake < C > ( chain : C , denom : String )
1404+ where
1405+ C : CwEnv + AltSigner ,
1406+ C :: Sender : Addressable ,
1407+ {
1408+ let commitment = Commitment {
1409+ denom : denom. clone ( ) ,
1410+ security : SecurityLevel {
1411+ max_penalty_percent : 25 ,
1412+ unbonding_period : 1000 ,
1413+ } ,
1414+ } ;
1415+
1416+ // Create 4 flows that all use the same reference token
1417+ let flows = vec ! [
1418+ SplitFlow {
1419+ consumer: nodes:: Counterparty :: Caller { } ,
1420+ shares: vec![ commitment. clone( ) ] ,
1421+ } ,
1422+ SplitFlow {
1423+ consumer: nodes:: Counterparty :: Caller { } ,
1424+ shares: vec![ commitment. clone( ) ] ,
1425+ } ,
1426+ SplitFlow {
1427+ consumer: nodes:: Counterparty :: Caller { } ,
1428+ shares: vec![ commitment. clone( ) ] ,
1429+ } ,
1430+ SplitFlow {
1431+ consumer: nodes:: Counterparty :: Caller { } ,
1432+ shares: vec![ commitment. clone( ) ] ,
1433+ } ,
1434+ ] ;
1435+
1436+ // Set up contracts
1437+ let weighting = TokenWeightingContract :: new ( TOKEN_WEIGHTING_CONTRACT_ID , chain. clone ( ) ) ;
1438+ weighting. upload ( ) . unwrap ( ) ;
1439+
1440+ let staking = TokenStakingContract :: new ( "staking" , chain. clone ( ) ) ;
1441+ staking. upload ( ) . unwrap ( ) ;
1442+
1443+ let mut fan_in = FanInContract :: new ( FAN_IN_CONTRACT_ID , chain. clone ( ) ) ;
1444+ fan_in. upload ( ) . unwrap ( ) ;
1445+
1446+ let splitter = SplitterContract :: new ( SPLITTER_CONTRACT_ID , chain. clone ( ) ) ;
1447+ splitter. upload ( ) . unwrap ( ) ;
1448+
1449+ // Configure flows with weighting contracts
1450+ let mut configured_flows = flows;
1451+ for flow in configured_flows. iter_mut ( ) {
1452+ let terms = RelativeWeights {
1453+ reference : commitment. clone ( ) ,
1454+ secondary : vec ! [ ] , // No secondary tokens in this test
1455+ } ;
1456+
1457+ flow. consumer = nodes:: Counterparty :: Create {
1458+ code_id : weighting. code_id ( ) . unwrap ( ) ,
1459+ msg : serde_json:: to_value ( token_weighting:: InstantiateMsg {
1460+ terms,
1461+ reward_denoms : None ,
1462+ provider : nodes:: Counterparty :: Caller { } ,
1463+ slasher : None ,
1464+ admin : None ,
1465+ } )
1466+ . unwrap ( ) ,
1467+ label : "Token Weighting" . to_string ( ) ,
1468+ admin : nodes:: ContractAdmin :: None ( ) ,
1469+ }
1470+ }
1471+
1472+ // Instantiate the splitter with fan-in as provider
1473+ let msg = InstantiateMsg {
1474+ provider : nodes:: Counterparty :: Create {
1475+ code_id : fan_in. code_id ( ) . unwrap ( ) ,
1476+ msg : serde_json:: to_value ( fan_in:: InstantiateMsg {
1477+ manager : chain. sender ( ) . to_string ( ) ,
1478+ consumer : nodes:: Counterparty :: Caller { } ,
1479+ } )
1480+ . unwrap ( ) ,
1481+ label : "Fan In" . to_string ( ) ,
1482+ admin : nodes:: ContractAdmin :: None ( ) ,
1483+ } ,
1484+ flows : configured_flows,
1485+ } ;
1486+ splitter. instantiate ( & msg, None , None ) . unwrap ( ) ;
1487+
1488+ // Set up fan-in
1489+ let config = splitter. config ( ) . unwrap ( ) ;
1490+ let provider = Addr :: unchecked ( config. provider ) ;
1491+ fan_in. set_default_address ( & provider) ;
1492+
1493+ // Set up staking contract
1494+ staking
1495+ . instantiate (
1496+ & rstk_token_staking:: msg:: InstantiateMsg {
1497+ commitment : commitment. clone ( ) ,
1498+ consumer : nodes:: Counterparty :: Existing {
1499+ contract : fan_in. addr_str ( ) . unwrap ( ) ,
1500+ } ,
1501+ } ,
1502+ None ,
1503+ None ,
1504+ )
1505+ . unwrap ( ) ;
1506+
1507+ fan_in
1508+ . add_input ( staking. addr_str ( ) . unwrap ( ) , commitment. clone ( ) , None )
1509+ . unwrap ( ) ;
1510+
1511+ // Get consumers for testing
1512+ let consumers_response = splitter. consumers ( ) . unwrap ( ) ;
1513+ assert_eq ! ( consumers_response. consumers. len( ) , 4 ) ;
1514+
1515+ // Initial stake
1516+ staking. stake ( & coins ( 1000 , & denom) ) . unwrap ( ) ;
1517+ chain. next_block ( ) . unwrap ( ) ;
1518+
1519+ // Verify initial power for all consumers
1520+ for consumer_info in consumers_response. consumers . iter ( ) {
1521+ weighting. set_address ( & Addr :: unchecked ( & consumer_info. consumer ) ) ;
1522+
1523+ let power = weighting
1524+ . voting_power_at_height ( chain. sender ( ) , None )
1525+ . unwrap ( ) ;
1526+ assert_eq ! ( power. power, Uint128 :: new( 1000 ) ) ;
1527+
1528+ let total_power = weighting. total_power_at_height ( None ) . unwrap ( ) ;
1529+ assert_eq ! ( total_power. power, Uint128 :: new( 1000 ) ) ;
1530+ }
1531+
1532+ // Unstake and verify power update
1533+ staking. unstake ( coin ( 400 , denom. clone ( ) ) ) . unwrap ( ) ;
1534+ chain. next_block ( ) . unwrap ( ) ;
1535+
1536+ // Verify updated power for all consumers
1537+ for consumer_info in consumers_response. consumers . iter ( ) {
1538+ weighting. set_address ( & Addr :: unchecked ( & consumer_info. consumer ) ) ;
1539+
1540+ let power = weighting
1541+ . voting_power_at_height ( chain. sender ( ) , None )
1542+ . unwrap ( ) ;
1543+ assert_eq ! ( power. power, Uint128 :: new( 600 ) ) ;
1544+
1545+ let total_power = weighting. total_power_at_height ( None ) . unwrap ( ) ;
1546+ assert_eq ! ( total_power. power, Uint128 :: new( 600 ) ) ;
1547+ }
1548+
1549+ // Complete unstaking process
1550+ chain. wait_seconds ( 1001 ) . unwrap ( ) ;
1551+ staking. withdraw_unbonded ( None ) . unwrap ( ) ;
1552+
1553+ // Final verification that power remains correct
1554+ for consumer_info in consumers_response. consumers . iter ( ) {
1555+ weighting. set_address ( & Addr :: unchecked ( & consumer_info. consumer ) ) ;
1556+
1557+ let power = weighting
1558+ . voting_power_at_height ( chain. sender ( ) , None )
1559+ . unwrap ( ) ;
1560+ assert_eq ! ( power. power, Uint128 :: new( 600 ) ) ;
1561+
1562+ let total_power = weighting. total_power_at_height ( None ) . unwrap ( ) ;
1563+ assert_eq ! ( total_power. power, Uint128 :: new( 600 ) ) ;
1564+ }
1565+ }
0 commit comments