diff --git a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm
index 0059c300216579fe71a647c516ae913cae408a2e..4e37d4101a2d12f63345fc1ba4b5e05e99dbd912 100644
Binary files a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ
diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs
index ea9f60afd9952a89a4afa0a2e5b8f217825b1644..b1199d2891db12eb78dd60bbc8b36db7300651fe 100644
--- a/substrate/node/runtime/src/lib.rs
+++ b/substrate/node/runtime/src/lib.rs
@@ -58,8 +58,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	spec_name: create_runtime_str!("node"),
 	impl_name: create_runtime_str!("substrate-node"),
 	authoring_version: 10,
-	spec_version: 36,
-	impl_version: 39,
+	spec_version: 37,
+	impl_version: 40,
 	apis: RUNTIME_API_VERSIONS,
 };
 
diff --git a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm
index f3ccde68d4398f18d7df982f890753e6e9b720d2..d3cd9bbcfb4e7b91cfce9282a20269b74c7ffe75 100644
Binary files a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm and b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm differ
diff --git a/substrate/srml/democracy/src/lib.rs b/substrate/srml/democracy/src/lib.rs
index fb2ee276681d538715de9b1f7ffe954efc6cb7d7..befbb2082dd5d77e6a5761d5cb100888fc9bc5ac 100644
--- a/substrate/srml/democracy/src/lib.rs
+++ b/substrate/srml/democracy/src/lib.rs
@@ -22,7 +22,7 @@ use rstd::prelude::*;
 use rstd::result;
 use primitives::traits::{Zero, As, Bounded};
 use parity_codec::{Encode, Decode};
-use srml_support::{StorageValue, StorageMap, Parameter, Dispatchable, IsSubType};
+use srml_support::{StorageValue, StorageMap, Parameter, Dispatchable, IsSubType, EnumerableStorageMap};
 use srml_support::{decl_module, decl_storage, decl_event, ensure};
 use srml_support::traits::{Currency, LockableCurrency, WithdrawReason, ArithmeticType, LockIdentifier};
 use srml_support::dispatch::Result;
@@ -40,6 +40,8 @@ pub type ReferendumIndex = u32;
 /// A number of lock periods.
 pub type LockPeriods = i8;
 
+const MAX_RECURSION_LIMIT: u32 = 16;
+
 /// A number of lock periods, plus a vote, one way or the other.
 #[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Default)]
 #[cfg_attr(feature = "std", derive(Debug))]
@@ -156,6 +158,22 @@ decl_module! {
 				runtime_io::print(e);
 			}
 		}
+
+		/// Delegate vote.
+		pub fn delegate(origin, to: T::AccountId, lock_periods: LockPeriods) -> Result {
+			let who = ensure_signed(origin)?;
+			<Delegations<T>>::insert(who.clone(), (to.clone(), lock_periods.clone()));
+			Self::deposit_event(RawEvent::Delegated(who, to));
+			Ok(())
+		}
+
+		/// Undelegate vote.
+		fn undelegate(origin) -> Result {
+			let who = ensure_signed(origin)?;
+			<Delegations<T>>::remove(who.clone());
+			Self::deposit_event(RawEvent::Undelegated(who));
+			Ok(())
+		}
 	}
 }
 
@@ -217,6 +235,9 @@ decl_storage! {
 		/// voter when called with the referendum (you'll get the default `Vote` value otherwise). If you don't want to check
 		/// `voters_for`, then you can also check for simple existence with `VoteOf::exists` first.
 		pub VoteOf get(vote_of): map (ReferendumIndex, T::AccountId) => Vote;
+
+		/// Get the account (and lock periods) to which another account is delegating vote.
+		pub Delegations get(delegations): linked_map T::AccountId => (T::AccountId, LockPeriods);
 	}
 }
 
@@ -230,6 +251,8 @@ decl_event!(
 		NotPassed(ReferendumIndex),
 		Cancelled(ReferendumIndex),
 		Executed(ReferendumIndex, bool),
+		Delegated(AccountId, AccountId),
+		Undelegated(AccountId),
 	}
 );
 
@@ -268,10 +291,9 @@ impl<T: Trait> Module<T> {
 
 	/// Get the voters for the current proposal.
 	pub fn tally(ref_index: ReferendumIndex) -> (BalanceOf<T>, BalanceOf<T>, BalanceOf<T>) {
-		Self::voters_for(ref_index).iter()
+		let (approve, against, capital): (BalanceOf<T>, BalanceOf<T>, BalanceOf<T>) = Self::voters_for(ref_index).iter()
 			.map(|voter| (
-				T::Currency::total_balance(voter),
-				Self::vote_of((ref_index, voter.clone())),
+				T::Currency::total_balance(voter), Self::vote_of((ref_index, voter.clone()))
 			))
 			.map(|(bal, vote)|
 				if vote.is_aye() {
@@ -279,7 +301,42 @@ impl<T: Trait> Module<T> {
 				} else {
 					(Zero::zero(), bal * BalanceOf::<T>::sa(vote.multiplier() as u64), bal)
 				}
-			).fold((Zero::zero(), Zero::zero(), Zero::zero()), |(a, b, c), (d, e, f)| (a + d, b + e, c + f))
+			).fold((Zero::zero(), Zero::zero(), Zero::zero()), |(a, b, c), (d, e, f)| (a + d, b + e, c + f));
+		let (del_approve, del_against, del_capital) = Self::tally_delegation(ref_index);
+		(approve + del_approve, against + del_against, capital + del_capital)
+	}
+
+	/// Get the delegated voters for the current proposal.
+	/// I think this goes into a worker once https://github.com/paritytech/substrate/issues/1458 is done. 
+	fn tally_delegation(ref_index: ReferendumIndex) -> (BalanceOf<T>, BalanceOf<T>, BalanceOf<T>) {
+		Self::voters_for(ref_index).iter()
+			.fold((Zero::zero(), Zero::zero(), Zero::zero()), |(approve_acc, against_acc, capital_acc), voter| {
+				let vote = Self::vote_of((ref_index, voter.clone()));
+				let (votes, balance) = Self::delegated_votes(ref_index, voter.clone(), vote.multiplier(), MAX_RECURSION_LIMIT);
+				if vote.is_aye() {
+					(approve_acc + votes, against_acc, capital_acc + balance)
+				} else {
+					(approve_acc, against_acc + votes, capital_acc + balance)
+				}
+			})
+	}
+
+	fn delegated_votes(
+		ref_index: ReferendumIndex,
+		to: T::AccountId,
+		min_lock_periods: LockPeriods,
+		recursion_limit: u32,
+	) -> (BalanceOf<T>, BalanceOf<T>) {
+		if recursion_limit == 0 { return (Zero::zero(), Zero::zero()); }
+		<Delegations<T>>::enumerate()
+			.filter(|(delegator, (delegate, _))| *delegate == to && !<VoteOf<T>>::exists(&(ref_index, delegator.clone())))
+			.fold((Zero::zero(), Zero::zero()), |(votes_acc, balance_acc), (delegator, (_delegate, periods))| {
+				let lock_periods = if min_lock_periods <= periods { min_lock_periods } else { periods };
+				let balance = T::Currency::total_balance(&delegator);
+				let votes = T::Currency::total_balance(&delegator) * BalanceOf::<T>::sa(lock_periods as u64);
+				let (del_votes, del_balance) = Self::delegated_votes(ref_index, delegator, lock_periods, recursion_limit - 1);
+				(votes_acc + votes + del_votes, balance_acc + balance + del_balance)
+			})
 	}
 
 	// Exposed mutables.
@@ -564,6 +621,158 @@ mod tests {
 			assert_eq!(Democracy::voters_for(r), vec![1]);
 			assert_eq!(Democracy::vote_of((r, 1)), AYE);
 			assert_eq!(Democracy::tally(r), (10, 0, 10));
+			
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+			assert_eq!(Balances::free_balance(&42), 2);
+		});
+	}
+
+	#[test]
+	fn single_proposal_should_work_with_delegation() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(1);
+
+			assert_ok!(propose_set_balance(1, 2, 1));
+
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+			System::set_block_number(2);
+			let r = 0;
+
+			// Delegate vote.
+			assert_ok!(Democracy::delegate(Origin::signed(2), 1, 100));
+
+			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
+
+			assert_eq!(Democracy::referendum_count(), 1);
+			assert_eq!(Democracy::voters_for(r), vec![1]);
+			assert_eq!(Democracy::vote_of((r, 1)), AYE);
+
+			// Delegated vote is counted.
+			assert_eq!(Democracy::tally(r), (30, 0, 30));
+
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+
+			assert_eq!(Balances::free_balance(&42), 2);
+		});
+	}
+
+	#[test]
+	fn single_proposal_should_work_with_cyclic_delegation() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(1);
+
+			assert_ok!(propose_set_balance(1, 2, 1));
+
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+			System::set_block_number(2);
+			let r = 0;
+
+			// Check behaviour with cycle.
+			assert_ok!(Democracy::delegate(Origin::signed(2), 1, 100));
+			assert_ok!(Democracy::delegate(Origin::signed(3), 2, 100));
+			assert_ok!(Democracy::delegate(Origin::signed(1), 3, 100));
+			
+			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
+
+			assert_eq!(Democracy::referendum_count(), 1);
+			assert_eq!(Democracy::voters_for(r), vec![1]);
+
+			// Delegated vote is counted.
+			assert_eq!(Democracy::tally(r), (60, 0, 60));
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+
+			assert_eq!(Balances::free_balance(&42), 2);
+		});
+	}
+
+	#[test]
+	/// If transactor already voted, delegated vote is overwriten.
+	fn single_proposal_should_work_with_vote_and_delegation() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(1);
+
+			assert_ok!(propose_set_balance(1, 2, 1));
+
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+			System::set_block_number(2);
+			let r = 0;
+
+			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
+
+			// Vote.
+			assert_ok!(Democracy::vote(Origin::signed(2), r, AYE));
+
+			// Delegate vote.
+			assert_ok!(Democracy::delegate(Origin::signed(2), 1, 100));
+
+			assert_eq!(Democracy::referendum_count(), 1);
+			assert_eq!(Democracy::voters_for(r), vec![1, 2]);
+			assert_eq!(Democracy::vote_of((r, 1)), AYE);
+
+			// Delegated vote is not counted.
+			assert_eq!(Democracy::tally(r), (30, 0, 30));
+
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+
+			assert_eq!(Balances::free_balance(&42), 2);
+		});
+	}
+
+	#[test]
+	fn single_proposal_should_work_with_undelegation() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(1);
+
+			assert_ok!(propose_set_balance(1, 2, 1));
+
+			// Delegate and undelegate vote.
+			assert_ok!(Democracy::delegate(Origin::signed(2), 1, 100));
+			assert_ok!(Democracy::undelegate(Origin::signed(2)));
+
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+			System::set_block_number(2);
+			let r = 0;
+			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
+
+			assert_eq!(Democracy::referendum_count(), 1);
+			assert_eq!(Democracy::voters_for(r), vec![1]);
+			assert_eq!(Democracy::vote_of((r, 1)), AYE);
+
+			// Delegated vote is not counted.
+			assert_eq!(Democracy::tally(r), (10, 0, 10));
+
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+
+			assert_eq!(Balances::free_balance(&42), 2);
+		});
+	}
+
+	#[test]
+	/// If transactor voted, delegated vote is overwriten.
+	fn single_proposal_should_work_with_delegation_and_vote() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(1);
+
+			assert_ok!(propose_set_balance(1, 2, 1));
+
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+			System::set_block_number(2);
+			let r = 0;
+
+			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
+
+			// Delegate vote.
+			assert_ok!(Democracy::delegate(Origin::signed(2), 1, 100));
+
+			// Vote.
+			assert_ok!(Democracy::vote(Origin::signed(2), r, AYE));
+
+			assert_eq!(Democracy::referendum_count(), 1);
+			assert_eq!(Democracy::voters_for(r), vec![1, 2]);
+			assert_eq!(Democracy::vote_of((r, 1)), AYE);
+
+			// Delegated vote is not counted.
+			assert_eq!(Democracy::tally(r), (30, 0, 30));
 
 			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
 
@@ -774,6 +983,29 @@ mod tests {
 		});
 	}
 
+	#[test]
+	fn lock_voting_should_work_with_delegation() {
+		with_externalities(&mut new_test_ext_with_public_delay(1), || {
+			System::set_block_number(1);
+			let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove, 0).unwrap();
+			assert_ok!(Democracy::vote(Origin::signed(1), r, Vote::new(false, 6)));
+			assert_ok!(Democracy::vote(Origin::signed(2), r, Vote::new(true, 5)));
+			assert_ok!(Democracy::vote(Origin::signed(3), r, Vote::new(true, 4)));
+			assert_ok!(Democracy::vote(Origin::signed(4), r, Vote::new(true, 3)));
+			assert_ok!(Democracy::delegate(Origin::signed(5), 2, 2));
+			assert_ok!(Democracy::vote(Origin::signed(6), r, Vote::new(false, 1)));
+
+			assert_eq!(Democracy::tally(r), (440, 120, 210));
+
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+
+			System::set_block_number(2);
+			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+
+			assert_eq!(Balances::free_balance(&42), 2);
+		});
+	}
+
 	#[test]
 	fn controversial_low_turnout_voting_should_work() {
 		with_externalities(&mut new_test_ext(), || {